当前位置:   article > 正文

django rest framework 用户认证

django rest framework 用户认证
  1. BaseAuthentication 类:
  2. django rest framework 通过 BaseAuthentication 实现认证功能
  3. 无论是自定义的认证类还是 rest framework 自带的认证类都应该继承 BaseAuthentication
  4. BaseAuthentication 中有两个方法 authenticate 和 authenticate_header, 其中 authenticate 方法必须实现
  5. 如果用户需要自定义认证方法则继承 BaseAuthentication 重写 authenticate 方法即可

 
 
models.py

  1. from django.db import models
  2. class UserInfo(models.Model):
  3. user_type_choices = (
  4. (1, '普通用户'),
  5. (2, 'VPI'),
  6. (3, 'SVPI'),
  7. )
  8. user_type = models.IntegerField(choices=user_type_choices)
  9. username = models.CharField(max_length=32, unique=True)
  10. password = models.CharField(max_length=64)
  11. class UserToken(models.Model):
  12. user = models.OneToOneField('UserInfo', models.CASCADE)
  13. token = models.CharField(max_length=64)

 
 
APP_DIR/utils/auth.py           # 在和 views.py 同级的目录创建 utils 包, 在 utils 中创建 auth.py 文件, 将认证相关的代码放入其中

  1. from rest_framework import exceptions
  2. from rest_framework.authentication import BaseAuthentication
  3. from app01 import models
  4. # 实现自定义的认证类
  5. class Authtication(BaseAuthentication):
  6. def authenticate(self, request):
  7. # 这儿的 request 对象不是 django 原生的 request 而是 rest_framework 内部进行封装过的 request
  8. # 使用 request._request 调用 django 原生的 request 对象
  9. token = request._request.GET.get('token')
  10. # 检查用户的 token 是否合法
  11. token_obj = models.UserToken.objects.filter(token=token).first()
  12. if not token_obj:
  13. # rest_framework 会在内部捕捉这个异常并返回给用户认证失败的信息
  14. raise exceptions.AuthenticationFailed('用户认证失败')
  15. # 在 rest_framework 内部会将这两个字段赋值给request以供后续调用
  16. return (token_obj.user, token_obj)

 
 
views.py

  1. from django.http import JsonResponse
  2. from rest_framework.views import APIView
  3. from app01.utils.auth import Authtication
  4. import hashlib
  5. import time
  6. # 生成 token 字符串
  7. def md5(user):
  8. ctime = str(time.time())
  9. m = hashlib.md5(bytes(user, encoding='utf-8'))
  10. m.update(bytes(ctime, encoding='utf-8'))
  11. return m.hexdigest()
  12. # 用户登录
  13. class AuthView(APIView):
  14. def post(self, request):
  15. ret = {'code':1000, 'msg':None}
  16. try:
  17. user = request._request.POST.get('username')
  18. pwd = request._request.POST.get('password')
  19. obj = models.UserInfo.objects.filter(username=user, password=pwd).first()
  20. if not obj:
  21. ret['code'] = 1001
  22. ret['msg'] = "用户名或密码错误"
  23. # 为登录用户创建token
  24. token = md5(user)
  25. #存在更新 不存在创建
  26. models.UserToken.objects.update_or_create(user=obj, defaults={'token':token})
  27. ret['token'] = token
  28. except:
  29. ret['code'] = 1002
  30. ret['msg'] = '请求异常'
  31. return JsonResponse(ret)
  32. # 业务代码
  33. class Order(APIView):
  34. # 注册自定义的认证类, 可以有多个, 从左到右进行认证匹配
  35. authentication_classes = [Authtication,]
  36. def get(self, request):
  37. # request.user 这个值等于 Authtication 返回的元组的第一个值
  38. # request.auth 这个值等于 Authtication 返回的元组的第二个值
  39. ret = {'code':1000, 'msg':None, 'data':None}
  40. ret['data'] = '欢迎使用本系统'
  41. return JsonResponse(ret)

 
 
rest_framework 内置的认证类:

  1. BasicAuthentication # 基于浏览器实现的 Basic 认证, ftp 使用网页登录时使用的就是 Basic 认证
  2. SessionAuthentication # 基于 django 的 user.is_active 进行认证
  3. TokenAuthentication # 简单的基于 token 的认证
  4. RemoteUserAuthentication # 简单的远程用户认证实现

 
 

配置全局生效的认证类和匿名用户:

  1. 自定义的认证类如果每次都在指定的类中使用 authentication_classes 指定那么就有可能出现大量的重复代码
  2. 我们可以通过全局设置让指定的认证类对继承至 APIView 的所有类生效
  3. settings.py
  4. REST_FRAMEWORK = {
  5. # 设置全局生效的认证类(可以有多个)
  6. # app01 为 django app 的名称
  7. # utils 为 app 目录下面的 utils 目录(这个目录必须包含 __init__.py 文件)
  8. # auth 为 utils 目录下面的 auth.py 文件
  9. # Authtication 为 auth.py 文件里面的 Authtication 类
  10. # 这儿的设置其实就是使用 from ... import ... 的路径
  11. 'DEFAULT_AUTHENTICATION_CLASSES': ["app01.utils.auth.Authtication",],
  12. #匿名用户配置
  13. 'UNAUTHENTICATED_USER': None, # 设置匿名用户的用户名, 默认为 AnonymousUser, 使用 request.user 查看
  14. 'UNAUTHENTICATED_TOKEN': None, # 设置匿名用户的 token, 默认为 None, 使用 request.auth 查看
  15. }

 
 

指定 View 类不使用全局的认证类:

  1. 在不使用全局认证类的 View 类中添加 authentication_classes = [] 或者 authentication_classes = ['xxxx']
  2. # authentication_classes = [] 表示不使用认证
  3. # authentication_classes = ['xxxx'], xxxx 表示当前类需要使用的认证类用于替换全局类

转载于:https://blog.51cto.com/hongchen99/2306783

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/天景科技苑/article/detail/876795
推荐阅读
相关标签
  

闽ICP备14008679号