28 自定义认证类

使用jwt自带的JSONWebTokenAuthentication认证类

需要带jwt+空格+token,不然不认证,非常麻烦

原来的认证类返回了request.user,是auth的user,不是自己自定义的user,所以需要自定义认证类

 

jwt之定制认证类:token放在header里

基于BaseAuthentication:没有提供获取user的方法

基于BaseJSONWebTokenAuthentication:可以由authenticate_credentials()获取user

auth.py

# 自定义认证类
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from rest_framework_jwt.settings import api_settings

jwt_decode_handler = api_settings.JWT_DECODE_HANDLER
import jwt
from .models import User

class JwtAuthentication(BaseAuthentication):
    def authenticate(self, request):
        # 第一步:取出前端传入的token串(从请求头的token中取出)
        jwt_value = request.META.get('HTTP_TOKEN')
        if jwt_value:
            # 验证token是否合法
            try:
                # 通过token,得到payload,在得到的过程中会校验,是否过期,是否被穿该
                payload = jwt_decode_handler(jwt_value)
            except jwt.ExpiredSignature:
                raise AuthenticationFailed('签名过期')
            except jwt.DecodeError:
                raise AuthenticationFailed('签名验证失败')
            except jwt.InvalidTokenError:
                raise AuthenticationFailed('未知错误')

            print(payload)
            # 有没有问题?每次都要去数据库查用户,效率低
            # 优先用这种
            user=User.objects.get(id=payload['user_id'])

            # 不需要查数据库,效率高,存在缺陷,
            # user=User(id=payload['user_id'],username=payload['username'])
            return (user, jwt_value)

        else:
            # 没带token串,没登录
            raise AuthenticationFailed('您没有携带token')

#局部使用views.py

# 局部使用,在视图类中配置
from .auth import JwtAuthentication
class TestView(APIView):
    # 自己写的认证类
    authentication_classes = [JwtAuthentication, ]

    def get(self, request):
        print(request.user) # 这就是当前登录用户
        return Response('你必须登录,才能看到我')

全局使用settings.py

# 全局使用,在配置文件中配置
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES':['app01.auth.JwtAuthentication'], # 全局生效

}
# 全局使用后,局部禁用
class LoginView(APIView):
    authentication_classes = []
    
    
# 注意:配置的所有认证,权限,频率。。。优先用视图类自己的,再用配置文件的,最后用drf内置的

补充:(settings.py)

# 补充:token过期时间很快,改改过期时间,配置7天过期
JWT_AUTH = {
    'JWT_RESPONSE_PAYLOAD_HANDLER': 'app01.common.jwt_response_payload_handler',
    # 过期时间7天
    'JWT_EXPIRATION_DELTA': datetime.timedelta(days=7),
}

post测试

 

posted @ 2022-02-08 21:20  甜甜de微笑  阅读(34)  评论(0编辑  收藏  举报