DRF令牌认证后如何在HTTP响应返回用户ID并跳转详情页
问题解答
是否需要在HTTP响应中包含用户ID?
需要。因为你要通过URL参数携带用户ID访问AccountDetails视图,前端必须先拿到用户ID才能构造对应的请求URL(比如/account/123),所以登录成功的响应里必须返回用户ID。
最佳实现方式及步骤
1. 修改登录序列化器,返回用户ID
在你的LogInSerializer中重写validate方法,把用户ID添加到登录响应数据里:
# serializer.py class LogInSerializer(TokenObtainPairSerializer): @classmethod def get_token(cls, user): token = super().get_token(user) user_data = ManagerSerializer(user).data for key, value in user_data.items(): # 可根据需求决定是否把ID加入token,即使不加,响应里也会单独返回 token[key] = value return token def validate(self, attrs): # 先调用父类验证逻辑拿到token数据 data = super().validate(attrs) # 把当前登录用户的ID添加到响应数据中 data['user_id'] = self.user.id return data
登录成功后,接口会返回refresh、access和user_id三个字段,前端直接取user_id即可构造请求URL。
2. 修正URL路径格式
你的urls.py中路径参数写法不规范,DRF需要指定参数类型(比如整数类型的pk),否则会被识别为字符串:
# urls.py router = routers.DefaultRouter() urlpatterns = [ path('', include(router.urls)), # 修正为<int:pk>,并添加末尾斜杠符合RESTful规范 path('account/<int:pk>/', AccountDetails.as_view()), ]
3. 给AccountDetails视图添加权限控制
为避免未登录用户访问,以及防止用户越权查看他人账户,需添加权限验证:
# view.py from rest_framework.permissions import IsAuthenticated from rest_framework.exceptions import PermissionDenied class AccountDetails(RetrieveAPIView): serializer_class = AccountSerializer queryset = Account.objects.all() # 要求用户必须登录才能访问 permission_classes = [IsAuthenticated] def get_object(self): # 限制用户只能查看自己的账户(可选,根据业务需求调整) obj = super().get_object() # 假设Account模型与User模型为一对一关联,关联字段为user if obj.user.id != self.request.user.id: raise PermissionDenied("你无权查看该账户信息") return obj
如果业务允许用户查看任意账户(不推荐),可去掉get_object的重写,但permission_classes仍需保留以确保只有登录用户能访问。
4. 前端请求逻辑
前端拿到登录返回的user_id后,构造请求URL(比如/account/${user_id}),并在请求头中携带access token(DRF的TokenAuthentication要求),即可访问用户的账户详情。
内容的提问来源于stack exchange,提问作者Florent
相关产品推荐
相关产品推荐

