目录django
(我是谁?)api
身份认证是将传入请求与一组标识凭据相关联的机制,而后,权限和限制策略可使用这些凭据来肯定是否应该容许该请求.服务器
REST框架提供了许多开箱即用的身份验证方案,还容许您实现自定义方案。
身份验证始终在视图的最开始,在发生权限和限制检查以前,以及容许任何其余代码继续以前运行。app
该 request.user
属性一般将设置为contrib.auth
包User
类的实例。框架
该 request.auth
属性用于任何其余身份验证信息,例如,它可用于表示请求已签名的身份验证令牌。dom
# 基于用户名和密码的认证 class BasicAuthentication(BaseAuthentication): pass # 基于Session的认证 class SessionAuthentication(BaseAuthentication): pass # 基于Tokend的认证 class TokenAuthentication(BaseAuthentication): pass # 基于远端用户的认证(专用用户管理服务器) class TokenAuthentication(BaseAuthentication): pass
身份验证方案始终定义为类列表。REST框架将尝试对列表中的每一个类进行身份验证,并将设置request.user和request.auth使用成功进行身份验证的第一个类的返回值。post
若是没有类进行身份验证,request.user则将设置为实例django.contrib.auth.models.AnonymousUser,request.auth并将其设置为None。url
的价值request.user和request.auth对身份认证的请求能够经过修改UNAUTHENTICATED_USER和UNAUTHENTICATED_TOKEN设置。rest
可使用该DEFAULT_AUTHENTICATION_CLASSES
设置全局设置默认认证方案。例如code
REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework.authentication.BasicAuthentication', 'rest_framework.authentication.SessionAuthentication', ) }
您还可使用APIView
基于类的视图在每一个视图或每一个视图集的基础上设置身份验证方案。
from rest_framework.authentication import SessionAuthentication, BasicAuthentication from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from rest_framework.views import APIView class ExampleView(APIView): authentication_classes = (SessionAuthentication, BasicAuthentication) permission_classes = (IsAuthenticated,) def get(self, request, format=None): content = { 'user': unicode(request.user), # `django.contrib.auth.User` instance. 'auth': unicode(request.auth), # None } return Response(content)
或者,若是您正在使用@api_view
具备基于功能的视图的装饰器。
@api_view(['GET']) @authentication_classes((SessionAuthentication, BasicAuthentication)) @permission_classes((IsAuthenticated,)) def example_view(request, format=None): content = { 'user': unicode(request.user), # `django.contrib.auth.User` instance. 'auth': unicode(request.auth), # None } return Response(content)
class UserInfo(models.Model): username = models.CharField(max_length=16) password = models.CharField(max_length=32) type = models.SmallIntegerField( choices=((0, '普通用户'), (1, 'VIP用户')), default=0 ) class Token(models.Model): user = models.OneToOneField(to='UserInfo') token_code = models.CharField(max_length=128)
from rest_framework.views import APIView from app2 import models from rest_framework.response import Response import hashlib, time def get_random_token(username): """ 根据用户名和时间戳生成随机token """ timestamp = str(time.time()) m = hashlib.md5(bytes(username, encoding="utf-8")) m.update(bytes(timestamp, encoding="utf-8")) return m.hexdigest() class LoginView(APIView): """ 校验用户名是否正确从而生成token的视图 """ def post(self, request): res = {"code": 0} # print(request.data) username = request.data.get("username") password = request.data.get("password") user = models.UserInfo.objects.filter(username=username, password=password).first() if user: token = get_random_token(username) models.Token.objects.update_or_create(defaults={"token_code": token}, user=user) res["token"] = token else: res["code"] = 1 res["error"] = "用户名或密码错误" return Response(res)
from rest_framework.authentication import BaseAuthentication from rest_framework.exceptions import AuthenticationFailed from app2 import models class MyAuth(BaseAuthentication): def authenticate(self, request): # if request.method in ["POST", "PUT", "DELETE"]: # 若是在表单中须要判断请求方式 因为表单是post请求,因此获取token 的方式为 request.data.get("token") # request.query_params为url中的参数 request_token = request.query_params.get("token", None) if not request_token: raise AuthenticationFailed('q.缺乏token') token_obj = models.Token.objects.filter(token_code=request_token).first() if not token_obj: raise AuthenticationFailed("无效的Token") # token_obj.user 经过token这张表的对象和user这个关联字段 找到 UserInfo表的对象及当前用户对象 return token_obj.user, request_token # else: # return None, None
# (用的很少) class CommentViewSet(ModelViewSet): queryset = models.Comment.objects.all() serializer_class = app01_serializers.CommentSerializer authentication_classes = [MyAuth, ]
# 在settings.py中配置 REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.MyAuth", ] }