2018-8-16JWTtoken用户登录认证思路分析9502751

JWT token在商城中的实现

class UserView(CreateAPIView):
serializer_class = CreateUserSerializer
  • 创建用户对象的视图函数,调用序列化器中的create方法来实现用户的保存
class CreateUserSerializer(serializers.ModelSerializer):
"""
创建用户序列化器具
"""
password2 = serializers.CharField(label="确认密码", required=True, allow_null=False, allow_blank=False, write_only=True)
sms_code = serializers.CharField(label="短信验证码", required=True, allow_null=False, allow_blank=False, write_only=True)
allow = serializers.CharField(label="同意协议", required=True, allow_null=False, allow_blank=False, write_only=True)
token = serializers.CharField(label='登录状态token', read_only=True) # 增加token字段 def validate_mobile(self, value):
if not re.match(r"^1[3456789]\d{9}$", value):
# if not re.match(r'^1[345789]\d{9}$', value): raise serializers.ValidationError("手机号码错误")
return value def validate_allow(self, value):
if value != "true":
raise serializers.ValidationError('请同意用户协议')
return value def validate(self, attrs):
if attrs["password"] != attrs["password2"]:
raise serializers.ValidationError("两次密码输入不一致")
redis_conn = get_redis_connection("verify_codes")
mobile = attrs["mobile"]
real_sms_code = redis_conn.get("sms_code_%s" % mobile)
if real_sms_code is None:
raise serializers.ValidationError("无效的短信验证码")
if real_sms_code.decode() != attrs['sms_code']:
raise serializers.ValidationError('短信验证码输入错误')
return attrs def create(self, validated_data):
del validated_data["password2"]
del validated_data["sms_code"]
del validated_data["allow"]
user = super().create(validated_data) user.set_password(validated_data["password"])
user.save()
# 为用户设置jwt验证字符串
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
payload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)
user.token = token
return user class Meta:
model = User
fields = ('id', 'username', 'password', 'password2', 'sms_code', 'mobile', 'allow', 'token')
extra_kwargs = {
'id': {"read_only": True},
"username": {
"max_length": 20,
"min_length": 5,
"error_messages": {
"max_length": "仅允许5-20个字符的用户名",
"min_length": '仅允许5-20个字符的用户名',
}
},
'password': {
'write_only': True,
'min_length': 8,
'max_length': 20,
'error_messages': {
'min_length': '仅允许8-20个字符的密码',
'max_length': '仅允许8-20个字符的密码',
}
}
}
  • 序列化器中对应的model模型中没有的字段进行补充

    • 增加用户名的属性为只读
    • 对用户的密码进行限制
  • 对手机号码进行验证
  • 对协议进行验证
  • 对密码和短信验证码进行验证
  • 创建用户的对象保存进到数据库中
  • 将保存的用户对象返回给前端
  • 为用户设置jwt验证字符串
  • 在返回的用户对象中增加一个额外的字段token(此token字段是中载荷为user对象)

用户登录

    from rest_framework_jwt.views import obtain_jwt_token

    url(r'^authorizations/$', obtain_jwt_token, name='authorizations'),
  • 原生的这个登录的方法中,默认返回到回来的数据是token

  • 但是在前端页面中我们需要在用户信息中展示用户的基本信息username,user对象

  • 对源码的分析如下所示:

    • 用户发送过来的登录请求是post请求
    • 默认回去post方法中执行
    • 执行的流程中会去将数据库中的token与用户发送过来的token做对比返回
    • 默认返回的数据由JWT_RESPONSE_PAYLOAD_HANDLER来决定
    • 重写JWT_RESPONSE_PAYLOAD_HANDLER并在配置文件中重新配置接可以返回我们想要的数据
  • 源代码的执行流程如下

obtain_jwt_token = ObtainJSONWebToken.as_view()

class JSONWebTokenAPIView(APIView):

    def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data) if serializer.is_valid():
user = serializer.object.get('user') or request.user
token = serializer.object.get('token')
response_data = jwt_response_payload_handler(token, user, request)
response = Response(response_data)
if api_settings.JWT_AUTH_COOKIE:
expiration = (datetime.utcnow() +
api_settings.JWT_EXPIRATION_DELTA)
response.set_cookie(api_settings.JWT_AUTH_COOKIE,
token,
expires=expiration,
httponly=True)
return response return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) class ObtainJSONWebToken(JSONWebTokenAPIView):
"""
API View that receives a POST with a user's username and password. Returns a JSON Web Token that can be used for authenticated requests.
"""
serializer_class = JSONWebTokenSerializer # 默认情况下会去api_settings中加载这个函数
jwt_response_payload_handler = api_settings.JWT_RESPONSE_PAYLOAD_HANDLER
  • 重写的代码
def jwt_response_payload_handler(token, user=None, request=None):
"""
自定义jwt认证成功返回数据
"""
return {
'token': token,
'user_id': user.id,
'username': user.username
}
  • 在配置文件中进行配置
# JWT
JWT_AUTH = {
'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),
'JWT_RESPONSE_PAYLOAD_HANDLER': 'users.utils.jwt_response_payload_handler',
}

2018-8-16JWTtoken用户登录认证思路分析9502751的更多相关文章

  1. 基于jwt的用户登录认证

    最近在app的开发过程中,做了一个基于token的用户登录认证,使用vue+node+mongoDB进行的开发,前来总结一下. token认证流程: 1:用户输入用户名和密码,进行登录操作,发送登录信 ...

  2. django rest_framework 实现用户登录认证

    django rest_framework 实现用户登录认证 1.安装 pip install djangorestframework 2.创建项目及应用 创建过程略 目录结构如图 3.设置setti ...

  3. 关于django用户登录认证中的cookie和session

    最近弄django的时候在用户登录这一块遇到了困难,网上的资料也都不完整或者存在缺陷. 写这篇文章的主要目的是对一些刚学django的新手朋友提供一些帮助.前提是你对django中的session和c ...

  4. ajax 的简单请求,get的加法运算,post加法运算,用户登录认证

    视图函数部分 from django.shortcuts import render, HttpResponse import time from app01.models import User i ...

  5. MongoDB 2.6配置副本集,支持端口号修改和用户登录认证

    mongoDB系列之(二):mongoDB 副本集 Mongodb2.6副本集验证部署和认证 副本集有以下特点: 1. 最小构成是:primary,secondary,arbiter,一般部署是:pr ...

  6. Shiro_认证思路分析

    [认证] 也就是登录. 1.获取当前的subject,调用SecurityUtils.getSubject() 2.测试当前的用户是否已经被认证,即是否登录.调用subject的isAuthentic ...

  7. 4、Shiro之IniRealm以及用户登录认证,角色认证,权限认证

    1.我们在项目test文件夹下面新建resourse文件夹并将她设置为资源文件夹: 2.在resourse文件夹下面新建user.ini文件 user.ini文件里面声明一个用户: 先写一个用户标签[ ...

  8. nginx 用户登录认证

    1.配置nginx server { listen ; server_name kibana.×××.com; location / { auth_basic "secret"; ...

  9. Shiro 登录认证源码详解

    Shiro 登录认证源码详解 Apache Shiro 是一个强大且灵活的 Java 开源安全框架,拥有登录认证.授权管理.企业级会话管理和加密等功能,相比 Spring Security 来说要更加 ...

随机推荐

  1. |ERROR|ERROR: missing data for column "createtime" (seg3 slice1 192.168.66.23:40001 pid=33370)之mysql换行符或者空格引起的问题

    1.最近的kettle的数据交换配置,启动kettle引起的错误,如下所示: |ERROR|ERROR: missing data pid=) 引发这个错误,并不是这个字段引起的错误,一般是这个字段临 ...

  2. KnocoutJs+Mvc+BootStrap 学习笔记(Mvc)

    Mvc   1.Html 增加扩展方法 using System.Web.Mvc; namespace KnockoutBootstrapMvc.Entensions { public static ...

  3. 无法创建链接服务器 "ORCL" 的 OLE DB 访问接口 "OraOLEDB.Oracle" 的实例 (错误:7302)

    原文:https://www.cnblogs.com/tiger2soft/p/6954308.html 在sqlserver中创建oracle的链接服务器时,提示此错误. 按照网上的方案,先后使用了 ...

  4. COOKIE和SESSION有什么区别?

    1,位置--session 在服务器端,cookie 在客户端(浏览器)2,形式--session 默认被存在在服务器的一个文件里(session 可以放在 文件.数据库.或内存中都可以),cooki ...

  5. 【回顾】html链接、头部

    1.HTML 链接 HTML 使用超级链接与网络上的另一个文档相连.几乎可以在所有的网页中找到链接.点击链接可以从一张页面跳转到另一张页面. HTML 超链接(链接) HTML使用标签 <a&g ...

  6. BZOJ4589 Hard Nim FWT 快速幂 博弈

    原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ4589.html 题目传送门 - BZOJ4589 题意 有 $n$ 堆石子,每一堆石子的取值为 $2$ ...

  7. POJ3740 Easy Finding 舞蹈链 DLX

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目 精确覆盖问题模板题 算法 DLX算法 学习DLX算法--传送门 代码 #include <cstring> ...

  8. forward 和redirect

    http://www.cnblogs.com/davidwang456/p/3998013.html

  9. 线程有gil锁

    gil锁作用: 遇到阻塞( 比如 recv() , accept() )就切换

  10. tp5的路由

    路由模式:普通.强制和混合 普通模式: //配置文件关闭路由,完全使用默认的PATH_INFO方式URL 'url_route_on' => false, 关闭路由后的普通模式任然可以通过操作方 ...