三大认证组件
认证组件
1、authentication
"""
系统:session认证
rest_framework.authentication.SessionAuthentication
ajax请求通过认证:
cookie中要携带 sessionid、csrftoken,请求头中要携带 x-csrftoken
第三方:jwt认证
rest_framework_jwt.authentication.JSONWebTokenAuthentication
ajax请求通过认证:
请求头中要携带 authorization,值为 jwt空格token
自定义:基于jwt、其它
1)自定义认证类,继承BaseAuthentication(或其子类),重写authenticate
2)authenticate中完成
拿到认证标识 auth
反解析出用户 user
前两步操作失败 返回None => 游客
前两步操作成功 返回user,auth => 登录用户
注:如果在某个分支抛出异常,直接定义失败 => 非法用户
"""
2、自定义认证类:基于jwt
from rest_framework. exceptions import AuthenticationFailed
import jwt
from rest_framework_jwt. authentication import BaseJSONWebTokenAuthentication
from rest_framework_jwt. authentication import jwt_decode_handler
3、普通自定义认证类
from rest_framework. authentication import BaseAuthentication
def authenticate ( self, request) :
auth = 从request中得到
user = 从auth中得到
if not user:
return None
return user, auth
权限组件
1、permission
"""
系统:
1)AllowAny:允许所有用户,校验方法直接返回True
2)IsAuthenticated:只允许登录用户
必须request.user和request.user.is_authenticated都通过
3)IsAuthenticatedOrReadOnly:游客只读,登录用户无限制
get、option、head 请求无限制
前台请求必须校验 request.user和request.user.is_authenticated
4)IsAdminUser:是否是后台用户
校验 request.user和request.user.is_staff is_staff(可以登录后台管理系统的用户)
自定义:基于auth的Group与Permission表
1)自定义权限类,继承BasePermission,重写has_permission
2)has_permission中完成
拿到登录用户 user <= request.user
校验user的分组或是权限
前两步操作失败 返回False => 无权限
前两步操作成功 返回True => 有权限
"""
2、自定义权限类:为 管理员 分组成员
from rest_framework. permissions import BasePermission
class AdminPermission ( BasePermission) :
def has_permission ( self, request, view) :
user = request. user
if not user:
return False
if not user. groups. filter ( name= '管理员' ) :
return False
return True
频率组件
1、throttle
"""
系统:
1)AnonRateThrottle:对同一IP游客的限制
2)UserRateThrottle:对同一IP登录用户的限制
必须在settings.py中
'DEFAULT_THROTTLE_RATES': {
'user': '10/min', # 登录的用户一分钟可以访问10次
'anon': '3/min', # 游客一分钟可以访问3次
}
在视图类中:
class TempAPIView(APIView):
...
throttle_classes = [AnonRateThrottle, UserRateThrottle]
自定义:基于auth的Group与Permission表
1)自定义频率类,继承SimpleRateThrottle,重写get_cache_key,明确scope
SimpleRateThrottle已经帮我们实现了 allow_request、wait
2)scope与settings.py的DEFAULT_THROTTLE_RATES配合使用
3)get_cache_key中完成
拿到限制信息 ident <= request中获取
没有限制信息 返回None => 不限制
有限制信息 返回限制信息字符串 => 有限制
"""
2、自定义频率类:一分钟一个手机号只允许访问一次接口
from rest_framework. throttling import SimpleRateThrottle
class ThreeMinRateThrottle ( SimpleRateThrottle) :
scope = 'sms'
def get_cache_key ( self, request, view) :
ident = request. data. get( 'mobile' )
if not ident:
return None
return self. cache_format % {
'scope' : self. scope,
'ident' : ident
}
'DEFAULT_THROTTLE_RATES' : {
'user' : '10/min' ,
'anon' : '3/min' ,
'sms' : '1/min' ,
}
jwt认证
JWT
1、工作原理
"""
1) jwt = base64(头部).base(载荷).hash256(base64(头部).base(载荷).密钥)
2) base64是可逆的算法、hash256是不可逆的算法
3) 密钥是固定的字符串,保存在服务器
"""
2、drf-jwt
官网
http: // getblimp. github. io/ django- rest- framework- jwt/
安装子:虚拟环境
pip install djangorestframework- jwt
使用:user/urls.py
from django. urls import path
from rest_framework_jwt. views import obtain_jwt_token
urlpatterns = [
path( 'login/' , obtain_jwt_token) ,
]
测试接口:post请求
"""
postman发生post请求
接口:http://api.luffy.cn:8000/user/login/
数据:
{
"username":"admin",
"password":"admin"
}
"""
3、drf-jwt开发
配置信息:JWT_AUTH到dev.py中
import datetime
JWT_AUTH = {
'JWT_EXPIRATION_DELTA' : datetime. timedelta( days= 1 ) ,
'JWT_RESPONSE_PAYLOAD_HANDLER' : 'user.utils.jwt_response_payload_handler' ,
}
序列化user:user/serializers.py(自己创建)
from rest_framework import serializers
from . import models
class UserModelSerializers ( serializers. ModelSerializer) :
class Meta :
model = models. User
fields = [ 'username' ]
自定义response:user/utils.py
from . serializers import UserModelSerializers
def jwt_response_payload_handler ( token, user= None , request= None ) :
return {
'status' : 0 ,
'msg' : 'ok' ,
'data' : {
'token' : token,
'user' : UserModelSerializers( user) . data
}
}
基于drf-jwt的全局认证:user/authentications.py(自己创建)
import jwt
from rest_framework. exceptions import AuthenticationFailed
from rest_framework_jwt. authentication import jwt_decode_handler
from rest_framework_jwt. authentication import get_authorization_header
from rest_framework_jwt. authentication import BaseJSONWebTokenAuthentication
class JSONWebTokenAuthentication ( BaseJSONWebTokenAuthentication) :
def authenticate ( self, request) :
jwt_value = get_authorization_header( request)
if not jwt_value:
raise AuthenticationFailed( 'Authorization 字段是必须的' )
try :
payload = jwt_decode_handler( jwt_value)
except jwt. ExpiredSignature:
raise AuthenticationFailed( '签名过期' )
except jwt. InvalidTokenError:
raise AuthenticationFailed( '非法用户' )
user = self. authenticate_credentials( payload)
return user, jwt_value
全局启用:settings/dev.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES' : (
'user.authentications.JSONWebTokenAuthentication' ,
) ,
}
局部启用禁用:任何一个cbv类首行
authentication_classes = [ ]
from user. authentications import JSONWebTokenAuthentication
authentication_classes = [ JSONWebTokenAuthentication]
多方式登录:user/utils.py
import re
from . models import User
from django. contrib. auth. backends import ModelBackend
class JWTModelBackend ( ModelBackend) :
def authenticate ( self, request, username= None , password= None , ** kwargs) :
try :
if re. match( r'^1[3-9]\d{9}$' , username) :
user = User. objects. get( mobile= username)
else :
user = User. objects. get( username= username)
except User. DoesNotExist:
return None
if user. check_password( password) and self. user_can_authenticate( user) :
return user
配置多方式登录:settings/dev.py
AUTHENTICATION_BACKENDS = [ 'user.utils.JWTModelBackend' ]
手动签发JWT:了解 - 可以拥有原生登录基于Model类user对象签发JWT
from rest_framework_jwt. settings import api_settings
jwt_payload_handler = api_settings. JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings. JWT_ENCODE_HANDLER
payload = jwt_payload_handler( user)
token = jwt_encode_handler( payload)