Loading

drf【认证(jwt)+权限】

一、认证(jwt)

1.安装`pyjwt`模块
pip install pyjwt
2.使用

login路由jwt编码

img
import jwt
import datetime
from django.conf import settings

token = jwt.encode(
            payload={
                'id': user_obj.id,
                'username': user_obj.username,
                'role': user_obj.role,
                'exp': datetime.datetime.utcnow() + datetime.timedelta(seconds=60 * 60 * 24 * 7)
            },
            key=settings.SECRET_KEY, algorithm="HS256", headers={'typ': 'jwt', 'alg': 'HS256'}
        )

认证组件中jwt解码

from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from django.conf import settings
import jwt


class User(object):
    def __init__(self, id, username, role, exp):
        self.id = id
        self.username = username
        self.role = role
        self.exp = exp


class RbacAuthentication(BaseAuthentication):

    def authenticate(self, request):
        # 1.获取jwt token
        jwt_token = request.query_params.get("token")
        if not jwt_token:
            raise AuthenticationFailed("认证失败")

        # 2.校验jwt token合法性
        try:
            verified_payload = jwt.decode(jwt_token, settings.SECRET_KEY, algorithms="HS256")
            # print(verified_payload)
            # {'id': 1, 'username': 'root','role':"", 'exp': 1717248737}
        except Exception as e:
            raise AuthenticationFailed("认证失败")

        # 3.返回 (request.user,request.auth)   request.user['id']
        return User(**verified_payload), jwt_token

    def authenticate_header(self, request):
        return "API"
3.全局应用

全局应用认证组件,login路由中设置authentication_classes = []

REST_FRAMEWORK = {
    "UNAUTHENTICATED_USER": None,
    "UNAUTHENTICATED_TOKEN": None,
    "DEFAULT_AUTHENTICATION_CLASSES": ["utils.auth.RbacAuthentication"],
    "DEFAULT_PERMISSION_CLASSES": ["utils.permission.RbacPermission"],
    "EXCEPTION_HANDLER": "utils.view.exception_handler"
}

补充:
如何错下了jwt而非pyjwt,移除命令:

pip uninstall jwt

二、权限

1.示例
from rest_framework.permissions import BasePermission
from django.conf import settings


class RbacPermission(BasePermission):
    message = "无权访问"

    def has_permission(self, request, view):
        # 1.当前用户的角色
        user_role = request.user.role

        # 2.当前用户=角色拥有的所有权限
        # {
        #     "user-list": ["get", 'post'],
        #     "user-detail": ["get", 'post', 'put', 'delete'],
        # }
        user_total_permissions = settings.PERMISSIONS[user_role]

        # 3.当前用户请求的路由信息
        router_name = request.resolver_match.view_name
        method = request.method.lower()
        method_list = user_total_permissions.get(router_name)
        if not method_list:
            return False

        if method not in method_list:
            return False

        return True
2.全局应用

全局应用全局应用权限组件,login路由中设置authentication_classes = []

REST_FRAMEWORK = {
    "UNAUTHENTICATED_USER": None,
    "UNAUTHENTICATED_TOKEN": None,
    "DEFAULT_AUTHENTICATION_CLASSES": ["utils.auth.RbacAuthentication"],
    "DEFAULT_PERMISSION_CLASSES": ["utils.permission.RbacPermission"],
    "EXCEPTION_HANDLER": "utils.view.exception_handler"
}
posted @ 2024-09-06 13:09  一只大学生  阅读(8)  评论(0编辑  收藏  举报