测试开发进阶(三十一)

来呀~

用户模块

Json Web Token认证

最常见的认证机制

  • Session认证

  • Token认证

Session认证

保持在服务端,增加服务器开销

分布式架构中,难以维持Session会话同步

CSRF攻击风险(跨站请求)

Token认证

保存在客户端

跨语言,跨平台

扩展性强

鉴权性能高

JWT(Json Web Token)

由三部分组成

  • header

声明类型

声明加密算法

base64加密,可以解密

  • playload

存放过期时间,签发用户等

可以添加用户的非敏感信息

base64加密,可以解密

  • signature

由三部分组成

使用base64加密之后的header + . + 使用base64加密之后的playload + 使用HS256算法加密,同时secret加盐处理

安装djangorestframework-jwt


   
   
  1. $ pip install djangorestframework-jwt

使用

setting.py中添加


   
   
  1. REST_FRAMEWORK = {

  2. 'DEFAULT_AUTHENTICATION_CLASSES': [

  3. # 使用JWT Token认证

  4. 'rest_framework_jwt.authentication.JSONWebTokenAuthentication',

  5. # Basic类型的认证(账号和密码)

  6. 'rest_framework.authentication.SessionAuthentication',

  7. # Session会话认证

  8. 'rest_framework.authentication.BasicAuthentication',

  9. ],

  10. }

添加路由

用户处:user/urls.py


   
   
  1. from django.urls import path

  2. from rest_framework_jwt.views import obtain_jwt_token

  3. urlpatterns = [

  4. path('login/', obtain_jwt_token),

  5. ]

主路由:

ApiTest/urls.py


   
   
  1. urlpatterns = [

  2. path('users/', include('user.urls'))

  3. ]

不登录的访问

登录后的返回内容


   
   
  1. HTTP 200 OK

  2. Allow: POST, OPTIONS

  3. Content-Type: application/json

  4. Vary: Accept

  5. {

  6. "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VybmFtZSI6Inpob25neGluIiwiZXhwIjoxNTcyMzA5MzQ2LCJlbWFpbCI6IjQ5MDMzNjUzNEBxcS5jb20ifQ.ZDEeBAgSuPyvh1KBnF1sSY9w22guSRHXm8sbgqEWusg"

  7. }


   
   
  1. import base64

  2. base64.b64decode('eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9')

  3. # b'{"typ":"JWT","alg":"HS256"}'

认证过期时间

./site-packages/rest_framework_jwt/settings.py

第40行


   
   
  1. 'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=300),

Token默认过期时间5分钟

自行修改过期时间 ApiTest/settings.py

过期时间为1天


   
   
  1. JWT_AUTH = {

  2. 'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1)

  3. }

请求Token 头


   
   
  1. 'JWT_AUTH_HEADER_PREFIX': 'JWT',

使用httpie发起包含token的内容

安装 httpie-jwt-auth插件


   
   
  1. $ export JWT_AUTH_TOKEN='你的token'

  2. $ export JWT_AUTH_PREFIX='JWT'

  3. $ http -A jwt :8000/projects/ page==2 size==2

修改载荷


   
   
  1. def jwt_response_payload_handler(token, user=None, request=None):

  2. """

  3. Returns the response data for both the login and refresh views.

  4. Override to return a custom response such as including the

  5. serialized representation of the User.

  6. Example:

  7. def jwt_response_payload_handler(token, user=None, request=None):

  8. return {

  9. 'token': token,

  10. 'user': UserSerializer(user, context={'request': request}).data

  11. }

  12. """

  13. return {

  14. 'token': token

  15. }

utils/jwt_handler.py重写


   
   
  1. def jwt_response_payload_handler(token, user=None, request=None):

  2. return {

  3. 'token': token,

  4. 'user_id': user.id,

  5. 'username': user.username,

  6. }


   
   
  1. JWT_AUTH = {

  2. 'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),

  3. 'JWT_PAYLOAD_GET_USERNAME_HANDLER': 'utils.jwt_handler.jwt_response_payload_handler'

  4. }

Django自带的用户模型

django.contrib.auth.models.User

查看settings.py可以发现,默认注册了 django.contrib.auth

注册

  • 用户名(6-20位,不重复)

  • 邮箱(符合邮箱格式)

  • 密码(6-20位,和确认密码一致)

  • 确认密码(6-20位,和密码一致)

user/serializers.py


   
   
  1. from rest_framework import serializers

  2. from django.contrib.auth.models import User

  3. class RegisterSerializer(serializers.ModelSerializer):

  4. password_conform = serializers.CharField(label='确认密码',

  5. min_length=6,

  6. max_length=20,

  7. write_only=True,

  8. help_text='确认密码',

  9. error_messages={'min_length': '仅允许6~20个字符的确认密码',

  10. 'max_length': '仅允许6~20个字符的确认密码'}

  11. )

  12. token = serializers.CharField(label='生成token',

  13. read_only=True)

  14. class Meta:

  15. model = User

  16. fields = ('id', 'username', 'password', 'email', 'password_conform', 'token')

  17. extra_kwargs = {

  18. 'username': {

  19. 'label': '用户名',

  20. 'help_text': '用户名',

  21. 'min_length': 6,

  22. 'max_length': 20,

  23. 'error_messages': {'min_length': '仅允许6~20个字符的用户名',

  24. 'max_length': '仅允许6~20个字符的用户名'}

  25. },

  26. 'email': {

  27. 'label': '邮箱',

  28. 'help_text': '邮箱',

  29. 'write_only': True,

  30. 'required': True

  31. },

  32. 'password': {

  33. 'label': '密码',

  34. 'help_text': '密码',

  35. 'write_only': True,

  36. 'min_length': 6,

  37. 'max_length': 20,

  38. 'error_messages': {'min_length': '仅允许6~20个字符的密码',

  39. 'max_length': '仅允许6~20个字符的密码'}

  40. }

  41. }

  42. def create(self, validated_data):

  43. pass

user/urls.py


   
   
  1. from django.urls import path

  2. from rest_framework_jwt.views import obtain_jwt_token

  3. from . import views

  4. urlpatterns = [

  5. path('login/', obtain_jwt_token),

  6. path('register/', views.RegisterView.as_view()),

  7. ]

user/views.py


   
   
  1. from rest_framework.generics import CreateAPIView

  2. from rest_framework_jwt.authentication import JSONWebTokenAuthentication

  3. from user.serializers import RegisterSerializer

  4. class RegisterView(CreateAPIView):

  5. serializer_class = RegisterSerializer

  6. authentication_classes = (JSONWebTokenAuthentication,)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值