请求中Access Token自动变更问题排查求助
问题
我通过以下代码实现登录接口,获取Access Token和Refresh Token:
class Employee_Login(APIView): permission_classes=[AllowAny] employee_login_data = serializers.employee_login_serializer def post(self,request): try: employee_data = self.employee_login_data(data=request.data) employee_data.is_valid(raise_exception=True) data = employee_data.validated_data employee = authenticate(request,email=data.get('email'), password= data.get('password')) if not employee: return Http404("Employee not found") if not employee.is_verified: raise ForbiddenException("Employee is not verified") payloads = { "user": "admin" if employee.is_admin and employee.is_verified and employee.is_staff else "staff" if employee.is_staff and employee.is_verified else "" } employee_detail = { "name":employee.name, "email":employee.email, "type":"admin" if employee.is_admin and employee.is_staff and employee.is_verified else "staff" if employee.is_admin and employee.is_verified else "" } refresh = RefreshToken.for_user(employee) refresh.payload.update(payloads) acess_token = str(refresh.access_token) refresh_token = str(refresh) return Response({"success":True, "data":employee_detail, "token":{"access":acess_token,"refresh":refresh_token}}) except Exception as e: return Response({"success":False,"message":str(e)})
但将获取到的Access Token用于以下自定义权限类时,出现异常:
class AdminPermission(permissions.BasePermission): def has_permission(self, request, view): print("Here",AccessToken(request.auth).payload) STAFF_METHODS = ['GET','POST','PATCH'] USER_METHODS = ['GET'] if request.method in USER_METHODS: return True print(AccessToken(request.auth)) if request.user.is_authenticated: if request.user.is_admin and request.user.is_staff and request.user.is_verified: return True if not request.user.is_admin and request.user.is_staff and request.user.is_verified and request.method in STAFF_METHODS: return True return False
print(AccessToken(request.auth))打印出的Token和请求中传入的完全不同,而且每次请求打印的内容都不一样,找不到问题所在,请求帮助。
解决方案
问题根源
Django REST Framework的JWT认证后端(如rest_framework_simplejwt)会自动解析请求中的Token,将request.auth设置为已解析完成的Token对象,而非原始的Token字符串。当你调用AccessToken(request.auth)时,相当于用已解析的payload重新生成了一个新的AccessToken,所以每次打印的内容都会变化。
修复步骤
- 获取原始Token字符串:如果需要查看请求传入的原始Token,直接从请求头中提取,不要使用
AccessToken()包裹request.auth:
# 从Authorization头提取原始Token raw_token = request.META.get('HTTP_AUTHORIZATION', '').split(' ')[-1] print(raw_token)
- 正确使用已解析的Token对象:
request.auth本身就是解析后的AccessToken实例,直接访问其属性即可:
# 直接获取payload print("Here", request.auth.payload) # 打印当前Token的字符串形式 print(str(request.auth))
- 优化权限类逻辑:原代码中
if request.method in USER_METHODS: return True会让所有GET请求直接跳过权限校验,这可能不符合预期,建议调整逻辑顺序:
class AdminPermission(permissions.BasePermission): def has_permission(self, request, view): STAFF_METHODS = ['GET','POST','PATCH'] # 未登录用户直接拒绝 if not request.user.is_authenticated: return False # 管理员拥有全量权限 if request.user.is_admin and request.user.is_staff and request.user.is_verified: return True # 普通员工仅允许指定请求方法 if request.user.is_staff and request.user.is_verified and request.method in STAFF_METHODS: return True return False
内容的提问来源于stack exchange,提问作者Roshan Ojha
相关产品推荐
相关产品推荐

