INSTALLED_APPS = [ # ... 'rest_framework', ] MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media') # Custom user table AUTH_USER_MODEL = ' api.User '
from django.conf.urls import url, include from django.contrib import admin from django.views.static import serve from django.conf import settings urlpatterns = [ URL (R & lt ' ^ ADMIN / ' , admin.site.urls), # route distribution URL (R & lt ' ^ API / ' , the include ( ' api.urls ' )), url(r'^media/(?P<path>).*', serve, {'document_root': settings.MEDIA_ROOT}), ]
from django.conf.urls import url, include from rest_framework.routers import SimpleRouter router = SimpleRouter() from . import views # Routing Registry # router.register ( 'Register', views.RegisterViewSet, 'Register') the urlpatterns = [ url('', include(router.urls)) ]
from django.contrib.auth.models import AbstractUser from django.db import models class User(AbstractUser): Mobile = models.CharField (MAX_LENGTH =. 11, UNIQUE = True, the verbose_name = ' mobile phone ' ) icon = models.ImageField(upload_to='icon', default='icon/default.png', verbose_name='头像') class Meta: named db_table, = ' o_user ' # table name defined verbose_name_plural = ' user table ' def __str__(self): return self.username class Book(models.Model): name = models.CharField(max_length=64, verbose_name='书名') class Meta: db_table = 'o_book' verbose_name_plural = '书表' def __str__(self): return self.name class Car(models.Model): name = models.CharField(max_length=64, verbose_name='车名') class Meta: db_table = 'o_car' verbose_name_plural = '车表' def __str__(self): return self.name
router.register('register', views.RegisterViewSet, 'register')
from rest_framework.viewsets import GenericViewSet, ModelViewSet from rest_framework import mixins from . import models, serializers class RegisterViewSet(GenericViewSet, mixins.CreateModelMixin): queryset = models.User.objects.filter(is_active=True).all() serializer_class = serializers.RegisterSerializer
from rest_framework import serializers from rest_framework.exceptions import ValidationError from . import models class RegisterSerializer(serializers.ModelSerializer): re_password = serializers.CharField(write_only=True, min_length=8, max_length=18) class Meta: model = models.User fields = ('username', 'password', 're_password', 'mobile') extra_kwargs = { 'password': { 'write_only': True, 'min_length': 8, 'max_length': 18 } } # Username and mobile hooks can customize local check (omitted) def validate(self, attrs): password = attrs.get('password') re_password = attrs.pop('re_password') if password != re_password: raise ValidationError({'re_password': 'password confirm error'}) return attrs # Needs to be rewritten create, the user needs to create a ciphertext DEF Create (Self, validated_data): # Create a table rewriting method modelserializer return models.User.objects.create_user (** validated_data) # the auth component functionality
router.register('user/center', views.UserCenterViewSet, 'center')
class UserCenterViewSet(GenericViewSet, mixins.RetrieveModelMixin): queryset = models.User.objects.filter(is_active=True).all() serializer_class = serializers.UserCenterSerializer
class UserCenterSerializer(serializers.ModelSerializer): class Meta: model = models.User fields = ('username', 'mobile', 'icon', 'email')
router.register('books', views.BookViewSet, 'book')
class BookViewSet(ModelViewSet): queryset = models.Book.objects.all() serializer_class = serializers.BookSerializer
class BookSerializer(serializers.ModelSerializer): class Meta: model = models.Book fields = ('name', )
""" 1) certification rules 2) How to Customize certification class 3) We generally do not need a custom class certification, the global configuration class certified third-party certification jwt components provided in the settings to """
""" 1) Custom certification class, class inheritance BaseAuthentication 2) must be rewritten authenticate (self, request) method No authentication information, return None: anonymous users (tourists) => anonymous users request.user also has value, it is "anonymous object (Anonymous)" Authentication information, and by a return (user, token): legal user => user object is stored in the request.user There authentication information is not passed, throw an exception: Illegal users """
""" 1) permission rules 2) How to customize permission class 3) We generally view class local configuration privileges class drf provided, but also custom permission class complete local configuration """
""" 1) custom permission class, class inheritance BasePermission 2) must be rewritten has_permission (self, request, view): Method Set permissions conditions, the conditions by return True: have permission Set permission condition, condition fails to return False: have permission 3) permission classes drf provided: AllowAny: Anonymous legitimate users IsAuthenticated: You must be logged, only legitimate users can IsAdminUser: must be admin backend users IsAuthenticatedOrReadOnly: anonymous read-only, legitimate users unlimited """
"" " Jwt advantage 1) there is no database writes, efficient 2) does not exist the server token, low power 3) are issued check algorithm, cluster """
""" 1) jwt points three-stage: The head-signed (head.payload.sign). 2) the head and body are reversible encryption, so that the server can counter solved user objects; the signature is not reversible encryption to ensure the security of the whole of the token 3) the head body signature three parts, all using a string json format encrypted base64-reversible encryption algorithm is generally irreversible encryption commonly used hash (md5) algorithm 4) The header is basic information: company information, program group information, encryption information using token { "Company": "Company Info", ... } Content 5) body is the key message: the user's home key, user name, when the issue of client information (device number, address), time expired { "user_id": 1, ... } 6) Safety information content signature: results of the first encrypted encryption result of + body + server is not open to the public md5 encrypted security code { "Head": "string encrypted header" "Payload": "string encrypted body", "Secret_key": "Security code" } """
""" 1) with the basic information stored in the dictionary json using head base64 string obtained by encrypting algorithm 2) with the key information storage json dictionary thereof in base64 string obtained by encrypting algorithm 3) a head body coupled with the encrypted string json security code stored in the dictionary information, the encryption algorithm employed to obtain hash md5 signature string User account and password can be obtained according to the User table objects, formed by three sections of the string. Spliced into the token returns to the front """
""" 1)将token按 . 拆分为三段字符串,第一段 头加密字符串 一般不需要做任何处理 2)第二段 体加密字符串,要反解出用户主键,通过主键从User表中就能得到登录用户,过期时间和设备信息都是安全信息,确保token没过期,且时同一设备来的 3)再用 第一段 + 第二段 + 服务器安全码 不可逆md5加密,与第三段 签名字符串 进行碰撞校验,通过后才能代表第二段校验得到的user对象就是合法的登录用户 """
""" 1)用账号密码访问登录接口,登录接口逻辑中调用 签发token 算法,得到token,返回给客户端,客户端自己存到cookies中 2)校验token的算法应该写在认证类中(在认证类中调用),全局配置给认证组件,所有视图类请求,都会进行认证校验,所以请求带了token,就会反解出user对象,在视图类中用request.user就能访问登录的用户 注:登录接口需要做 认证 + 权限 两个局部禁用 """
>: pip install djangorestframework-jwt
# api/urls.py urlpatterns = [ # ... url('^login/$', ObtainJSONWebToken.as_view()), ] # Postman请求:/api/login/,提供username和password即可
# drf-jwt的配置 import datetime # 配置必须放在drf配置的上面,才能起作用 JWT_AUTH = { # 配置过期时间 'JWT_EXPIRATION_DELTA': datetime.timedelta(days=7), } # drf配置(把配置放在最下方) REST_FRAMEWORK = { # 自定义三大认证配置类们 'DEFAULT_AUTHENTICATION_CLASSES': ['rest_framework_jwt.authentication.JSONWebTokenAuthentication'], # 'DEFAULT_PERMISSION_CLASSES': [], # 'DEFAULT_THROTTLE_CLASSES': [], }
from rest_framework.permissions import IsAuthenticated class UserCenterViewSet(GenericViewSet, mixins.RetrieveModelMixin): # 设置必须登录才能访问的权限类 permission_classes = [IsAuthenticated, ] queryset = models.User.objects.filter(is_active=True).all() serializer_class = serializers.UserCenterSerializer
""" 1)用 {"username": "你的用户", "password": "你的密码"} 访问 /api/login/ 接口等到 token 字符串 2)在请求头用 Authorization 携带 "jwt 登录得到的token" 访问 /api/user/center/1/ 接口访问个人中心 """
pycharm的debug介绍
1.向下一步,如果遇到调用方法,函数,当成一步走 2. 向下一步,如果遇到调用方法,函数,进入其中 3.向下一步,只走自己的代码(较少用到)
4.向下完成代码,直到下一个断点 5.显示所有断点(可编辑) 6.取消所有断点,再点击会再次出现断点 7.跳出当前方法,函数(完成),往下继续
""" 1)注册接口、个人中心接口、图书接口 2)认证组件 i)如何自定义认证类:继承谁、实现什么方法、方法体逻辑就是认证规则 ii)认证规则:游客、合法用户、方法用户 3)权限组件 i)如何自定义权限类:继承谁、实现什么方法、方法体逻辑就是权限规则 ii)权限规则:有权限、无权限 4)认证权限配置:局部 > 全局 > 默认 认证一般都是全局配置,所有登录注册接口要局部禁用 权限一般做局部配置 => 电商类项目,90%以上接口游客可以访问 权限一般做全局配置 => 邮箱项目,几乎所有接口都需要登录才能访问 5)jwt签发校验规则 6)drf-jwt框架的简单使用 """