1. JWT
1.1 简介
定义:JSON Web Token,目前最流行的跨域身份验证解决方案
原理: 服务器身份验证之后,将生成一个JSON对象并将其发送回用户。当用户与服务器进行后续通信时,客户在请求中发回JSON对象。服务器仅依赖于这个JSON对象来标识用户。为了防止用户篡改数据,服务器将在生成对象时添加签名。
优点: 服务器不保存任何会话数据,即服务器变为无状态,使其更容易扩展
构成: header、playload、signature
header:声明类型、加密算法(默认HS256)、base64加密(可解密)
playload:存放过期时间、用户的非敏感信息、base64加密(可解密)
signature:base64加密后的header + base64加密后的playload + (HS256+secret)加密串
1.2 JWT使用
from django. urls import path
from rest_framework_jwt. views import obtain_jwt_token
urlpatterns = [
path( 'login/' , obtain_jwt_token)
]
http : 8000 / user/ login/ username= zy password= 123456
http : 8000 / projects/ Authorization: "JWT token"
http - a zy: 123456 : 8000 / projects/
2. 登陆注册
2.1 注册需求
参数
输入/出
校验/描述
用户名
输入/出
6-20位,不能重复
邮箱
输入
合法格式,不能重复
密码
输入
6-20位,与确认密码一致
确认密码
输入
6-20位,与确认密码一致
token
输入
注册成功之后返回token
2.2 代码
Django 自带认证功能auth模块和User对象的基本操作
user模型需继承django自带的用户认证系统AbstractUser才可以使用
from rest_framework import serializers
from django. contrib. auth. models import User
from rest_framework. validators import UniqueValidator
from rest_framework_jwt. serializers import jwt_payload_handler, jwt_encode_handler
class RegisterSerializer ( serializers. ModelSerializer) :
password_confirm = serializers. CharField( label= '确认密码' , min_length= 6 , max_length= 20 , help_text= '确认密码' ,
write_only= True ,
error_messages= {
'min_length' : '仅允许6~20位字符的确认密码' ,
'max_length' : '仅允许6~20位字符的确认密码'
} )
token = serializers. CharField( label= 'token' , read_only= True )
class Meta :
model = User
fields = ( 'id' , 'username' , 'password' , 'email' , 'password_confirm' , 'token' )
extra_kwargs = {
'username' : {
'label' : '用户名' ,
'help_text' : '用户名' ,
'min_length' : 6 ,
'max_length' : 20 ,
'error_messages' : {
'min_length' : '仅允许6-20个字符的用户名' ,
'max_length' : '仅允许6-20个字符的用户名' ,
}
} ,
'email' : {
'label' : '邮箱' ,
'help_text' : '邮箱' ,
'write_only' : True ,
'required' : True ,
'validators' : [ UniqueValidator( queryset= User. objects. all ( ) , message= '此邮箱已注册' ) ] ,
} ,
'password' : {
'label' : '密码' ,
'help_text' : '密码' ,
'write_only' : True ,
'min_length' : 6 ,
'max_length' : 20 ,
'error_messages' : {
'min_length' : '仅允许6-20个字符的密码' ,
'max_length' : '仅允许6-20个字符的密码' ,
}
}
}
def validate ( self, attrs) :
if attrs. get( 'password' ) != attrs. get( 'password_confirm' ) :
raise serializers. ValidationError( '密码与确认密码不一致' )
return attrs
def create ( self, validated_data) :
validated_data. pop( 'password_confirm' )
user = User. objects. create_user( ** validated_data)
payload = jwt_payload_handler( user)
token = jwt_encode_handler( payload)
user. token = token
return user
from django. urls import path, include
from rest_framework_jwt. views import obtain_jwt_token
from . import views
urlpatterns = [
path( 'login/' , obtain_jwt_token) ,
path( 'register/' , views. RegisterView. as_view( ) )
]
from rest_framework. generics import CreateAPIView
from . import serializer
class RegisterView ( CreateAPIView) :
serializer_class = serializer. RegisterSerializer
def jwt_response_payload_handler ( token, user= None , request= None ) :
"""
Returns the response data for both the login and refresh views.
Override to return a custom response such as including the
serialized representation of the User.
Example:
def jwt_response_payload_handler(token, user=None, request=None):
return {
'token': token,
'user': UserSerializer(user, context={'request': request}).data
}
"""
return {
'token' : token,
'username' : user. username,
'user_id' : user. id
}
import datetime
JWT_AUTH = {
'JWT_EXPIRATION_DELTA' : datetime. timedelta( days= 1 ) ,
'JWT_AUTH_HEADER_PREFIX' : 'JWT' ,
'JWT_RESPONSE_PAYLOAD_HANDLER' : 'utils.jwt_handler.jwt_response_payload_handler' ,
}