认证

(我是谁?)

身份认证是将传入请求与一组标识凭据相关联的机制,然后,权限和限制策略可以使用这些凭据来确定是否应该允许该请求.

REST框架提供了许多开箱即用的身份验证方案,还允许您实现自定义方案。

身份验证始终在视图的最开始,在发生权限和限制检查之前,以及允许任何其他代码继续之前运行。

request.user 属性通常将设置为contrib.authUser类的实例。

request.auth 属性用于任何其他身份验证信息,例如,它可用于表示请求已签名的身份验证令牌。

DRF 5种验证方式

  1. # 基于用户名和密码的认证
  2. class BasicAuthentication(BaseAuthentication):
  3. pass
  4. # 基于Session的认证
  5. class SessionAuthentication(BaseAuthentication):
  6. pass
  7. # 基于Tokend的认证
  8. class TokenAuthentication(BaseAuthentication):
  9. pass
  10. # 基于远端用户的认证(专用用户管理服务器)
  11. class TokenAuthentication(BaseAuthentication):
  12. pass

如何确定身份验证?

身份验证方案始终定义为类列表。REST框架将尝试对列表中的每个类进行身份验证,并将设置request.user和request.auth使用成功进行身份验证的第一个类的返回值。

如果没有类进行身份验证,request.user则将设置为实例django.contrib.auth.models.AnonymousUser,request.auth并将其设置为None。

的价值request.user和request.auth对身份认证的请求可以通过修改UNAUTHENTICATED_USER和UNAUTHENTICATED_TOKEN设置。

设置身份验证方案

  1. 可以使用该DEFAULT_AUTHENTICATION_CLASSES设置全局设置默认认证方案。例如

    1. REST_FRAMEWORK = {
    2. 'DEFAULT_AUTHENTICATION_CLASSES': (
    3. 'rest_framework.authentication.BasicAuthentication',
    4. 'rest_framework.authentication.SessionAuthentication',
    5. )
    6. }
  2. 您还可以使用APIView基于类的视图在每个视图或每个视图集的基础上设置身份验证方案。

    1. from rest_framework.authentication import SessionAuthentication, BasicAuthentication
    2. from rest_framework.permissions import IsAuthenticated
    3. from rest_framework.response import Response
    4. from rest_framework.views import APIView
    5. class ExampleView(APIView):
    6. authentication_classes = (SessionAuthentication, BasicAuthentication)
    7. permission_classes = (IsAuthenticated,)
    8. def get(self, request, format=None):
    9. content = {
    10. 'user': unicode(request.user), # `django.contrib.auth.User` instance.
    11. 'auth': unicode(request.auth), # None
    12. }
    13. return Response(content)
  3. 或者,如果您正在使用@api_view具有基于功能的视图的装饰器。

    1. @api_view(['GET'])
    2. @authentication_classes((SessionAuthentication, BasicAuthentication))
    3. @permission_classes((IsAuthenticated,))
    4. def example_view(request, format=None):
    5. content = {
    6. 'user': unicode(request.user), # `django.contrib.auth.User` instance.
    7. 'auth': unicode(request.auth), # None
    8. }
    9. return Response(content)

案例: 基于自定义Token认证

第一步: 定义一个用户表和一个保存用户Token的表

  1. class UserInfo(models.Model):
  2. username = models.CharField(max_length=16)
  3. password = models.CharField(max_length=32)
  4. type = models.SmallIntegerField(
  5. choices=((0, '普通用户'), (1, 'VIP用户')),
  6. default=0
  7. )
  8. class Token(models.Model):
  9. user = models.OneToOneField(to='UserInfo')
  10. token_code = models.CharField(max_length=128)

第二步: 定义一个登陆视图

  1. from rest_framework.views import APIView
  2. from app2 import models
  3. from rest_framework.response import Response
  4. import hashlib, time
  5. def get_random_token(username):
  6. """
  7. 根据用户名和时间戳生成随机token
  8. """
  9. timestamp = str(time.time())
  10. m = hashlib.md5(bytes(username, encoding="utf-8"))
  11. m.update(bytes(timestamp, encoding="utf-8"))
  12. return m.hexdigest()
  13. class LoginView(APIView):
  14. """
  15. 校验用户名是否正确从而生成token的视图
  16. """
  17. def post(self, request):
  18. res = {"code": 0}
  19. # print(request.data)
  20. username = request.data.get("username")
  21. password = request.data.get("password")
  22. user = models.UserInfo.objects.filter(username=username, password=password).first()
  23. if user:
  24. token = get_random_token(username)
  25. models.Token.objects.update_or_create(defaults={"token_code": token}, user=user)
  26. res["token"] = token
  27. else:
  28. res["code"] = 1
  29. res["error"] = "用户名或密码错误"
  30. return Response(res)

第三步定义一个认证类

  1. from rest_framework.authentication import BaseAuthentication
  2. from rest_framework.exceptions import AuthenticationFailed
  3. from app2 import models
  4. class MyAuth(BaseAuthentication):
  5. def authenticate(self, request):
  6. # if request.method in ["POST", "PUT", "DELETE"]:
  7. # 如果在表单中需要判断请求方式 由于表单是post请求,所以获取token 的方式为 request.data.get("token")
  8. # request.query_params为url中的参数
  9. request_token = request.query_params.get("token", None)
  10. if not request_token:
  11. raise AuthenticationFailed('q.缺少token')
  12. token_obj = models.Token.objects.filter(token_code=request_token).first()
  13. if not token_obj:
  14. raise AuthenticationFailed("无效的Token")
  15. # token_obj.user 通过token这张表的对象和user这个关联字段 找到 UserInfo表的对象及当前用户对象
  16. return token_obj.user, request_token
  17. # else:
  18. # return None, None

第四步: 使用认证类

视图级别认证

  1. # (用的不多)
  2. class CommentViewSet(ModelViewSet):
  3. queryset = models.Comment.objects.all()
  4. serializer_class = app01_serializers.CommentSerializer
  5. authentication_classes = [MyAuth, ]

全局级别认证

  1. # 在settings.py中配置
  2. REST_FRAMEWORK = {
  3. "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.MyAuth", ]
  4. }

Django REST framework - 认证的更多相关文章

  1. Django Rest Framework(认证、权限、限制访问频率)

    阅读原文Django Rest Framework(认证.权限.限制访问频率) django_rest_framework doc django_redis cache doc

  2. 04 Django REST Framework 认证、权限和限制

    目前,我们的API对谁可以编辑或删除代码段没有任何限制.我们希望有更高级的行为,以确保: 代码片段始终与创建者相关联. 只有通过身份验证的用户可以创建片段. 只有代码片段的创建者可以更新或删除它. 未 ...

  3. Django REST framework认证权限和限制和频率

    认证.权限和限制 身份验证是将传入请求与一组标识凭据(例如请求来自的用户或其签名的令牌)相关联的机制.然后 权限 和 限制 组件决定是否拒绝这个请求. 简单来说就是: 认证确定了你是谁 权限确定你能不 ...

  4. Django REST Framework 认证 - 权限 - 限制

    一. 认证 (你是谁?) REST framework 提供了一些开箱即用的身份验证方案,并且还允许你实现自定义方案. 自定义Token认证 第一步 : 建表>>>> 定义一个 ...

  5. Django REST framework —— 认证组件源码分析

    我在前面的博客里已经讲过了,我们一般编写API的时候用的方式 class CoursesView(ViewSetMixin,APIView): pass 这种方式的有点是,灵活性比较大,可以根据自己的 ...

  6. django rest framework 认证组件

    1.认证组件 1.认证组件 1.认证组件 1.认证组件

  7. Django REST framework认证权限和限制 源码分析

    1.首先 我们进入这个initial()里面看下他内部是怎么实现的. 2.我们进入里面看到他实现了3个方法,一个认证,权限频率 3.我们首先看下认证组件发生了什么 权限: 啥都没返回,self.per ...

  8. Django REST framework 之 API认证

    RESTful API 认证 和 Web 应用不同,RESTful APIs 通常是无状态的, 也就意味着不应使用 sessions 或 cookies, 因此每个请求应附带某种授权凭证,因为用户授权 ...

  9. Django REST framework - 权限和限制

    目录 Django REST framework 权限和限制 (你能干什么) 设置权限的方法 案例 第一步: 定义一个权限类 第二步: 使用 视图级别 全局级别设置 --- 限制 (你一分钟能干多少次 ...

随机推荐

  1. js 实现二叉排序树

    二叉排序树或者是一棵空树,或者是具有下列性质的二叉树: (1)若左子树不空,则左子树上所有结点的值均小于或等于它的根结点的值: (2)若右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值: ...

  2. ios6--UILabel

    // // ViewController.m // 02-UILabel的使用 // // UILabel显示一段文字. #import "ViewController.h" @i ...

  3. oc85--利用宏定义简化单例

    //Singleton.h // 以后就可以使用interfaceSingleton来替代后面的方法声明. \表示下一行也是上一行的内容. #define interfaceSingleton(nam ...

  4. windows下写的脚本,在linux下执行失败

    Windows中的换行符为CRLF, 即正则表达式的rn(ASCII码为13和10), 而Unix(或Linux)换行符为LF, 即正则表达式的n. 在Windows和Linux下协同工作的时候, 往 ...

  5. PCB SQL SERVER 邮箱配置与发邮件

    一.开启SQL SERVER发邮件功能 --开启发邮件功能 reconfigure with override go reconfigure with override go 二.邮箱配置 1.代码创 ...

  6. Github提交本地版本是遇到的问题

    问题如下:*** Please tell me who you are. Run git config --global user.email "you@example.com" ...

  7. 解决Sql中DIstinct与Order By共同使用的冲突问题

    1.需求场景: 需要把最新更新文章的前五名作者展示出来. 2.解决问题第一步: select top 5 creator from table order by updateDate desc 结果: ...

  8. D3.js 力导向图(小气泡围绕中心气泡)

    html <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3 ...

  9. HTML+CSS(12)

    n  CSS浮动和清除 Float:让元素浮动,取值:left(左浮动).right(右浮动). Clear:清除浮动,取值:left(清除左浮动).right(清除右浮动).both(同时清除上面的 ...

  10. AIDL跨进程通信报Intent must be explicit

    在Android5.0机子上采用隐式启动来调试AIDL时,会出现Intent must be explicit的错误,原因是5.0的机子不允许使用隐式启动方式,解决的方法是:在启动intent时添加i ...