drf【认证(jwt)+权限】
一、认证(jwt)
1.安装`pyjwt`模块
pip install pyjwt
2.使用
login路由jwt编码
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"
}