2018-8-16JWTtoken用户登录认证思路分析9502751
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的更多相关文章
- 基于jwt的用户登录认证
最近在app的开发过程中,做了一个基于token的用户登录认证,使用vue+node+mongoDB进行的开发,前来总结一下. token认证流程: 1:用户输入用户名和密码,进行登录操作,发送登录信 ...
- django rest_framework 实现用户登录认证
django rest_framework 实现用户登录认证 1.安装 pip install djangorestframework 2.创建项目及应用 创建过程略 目录结构如图 3.设置setti ...
- 关于django用户登录认证中的cookie和session
最近弄django的时候在用户登录这一块遇到了困难,网上的资料也都不完整或者存在缺陷. 写这篇文章的主要目的是对一些刚学django的新手朋友提供一些帮助.前提是你对django中的session和c ...
- ajax 的简单请求,get的加法运算,post加法运算,用户登录认证
视图函数部分 from django.shortcuts import render, HttpResponse import time from app01.models import User i ...
- MongoDB 2.6配置副本集,支持端口号修改和用户登录认证
mongoDB系列之(二):mongoDB 副本集 Mongodb2.6副本集验证部署和认证 副本集有以下特点: 1. 最小构成是:primary,secondary,arbiter,一般部署是:pr ...
- Shiro_认证思路分析
[认证] 也就是登录. 1.获取当前的subject,调用SecurityUtils.getSubject() 2.测试当前的用户是否已经被认证,即是否登录.调用subject的isAuthentic ...
- 4、Shiro之IniRealm以及用户登录认证,角色认证,权限认证
1.我们在项目test文件夹下面新建resourse文件夹并将她设置为资源文件夹: 2.在resourse文件夹下面新建user.ini文件 user.ini文件里面声明一个用户: 先写一个用户标签[ ...
- nginx 用户登录认证
1.配置nginx server { listen ; server_name kibana.×××.com; location / { auth_basic "secret"; ...
- Shiro 登录认证源码详解
Shiro 登录认证源码详解 Apache Shiro 是一个强大且灵活的 Java 开源安全框架,拥有登录认证.授权管理.企业级会话管理和加密等功能,相比 Spring Security 来说要更加 ...
随机推荐
- |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=) 引发这个错误,并不是这个字段引起的错误,一般是这个字段临 ...
- KnocoutJs+Mvc+BootStrap 学习笔记(Mvc)
Mvc 1.Html 增加扩展方法 using System.Web.Mvc; namespace KnockoutBootstrapMvc.Entensions { public static ...
- 无法创建链接服务器 "ORCL" 的 OLE DB 访问接口 "OraOLEDB.Oracle" 的实例 (错误:7302)
原文:https://www.cnblogs.com/tiger2soft/p/6954308.html 在sqlserver中创建oracle的链接服务器时,提示此错误. 按照网上的方案,先后使用了 ...
- COOKIE和SESSION有什么区别?
1,位置--session 在服务器端,cookie 在客户端(浏览器)2,形式--session 默认被存在在服务器的一个文件里(session 可以放在 文件.数据库.或内存中都可以),cooki ...
- 【回顾】html链接、头部
1.HTML 链接 HTML 使用超级链接与网络上的另一个文档相连.几乎可以在所有的网页中找到链接.点击链接可以从一张页面跳转到另一张页面. HTML 超链接(链接) HTML使用标签 <a&g ...
- BZOJ4589 Hard Nim FWT 快速幂 博弈
原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ4589.html 题目传送门 - BZOJ4589 题意 有 $n$ 堆石子,每一堆石子的取值为 $2$ ...
- POJ3740 Easy Finding 舞蹈链 DLX
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目 精确覆盖问题模板题 算法 DLX算法 学习DLX算法--传送门 代码 #include <cstring> ...
- forward 和redirect
http://www.cnblogs.com/davidwang456/p/3998013.html
- 线程有gil锁
gil锁作用: 遇到阻塞( 比如 recv() , accept() )就切换
- tp5的路由
路由模式:普通.强制和混合 普通模式: //配置文件关闭路由,完全使用默认的PATH_INFO方式URL 'url_route_on' => false, 关闭路由后的普通模式任然可以通过操作方 ...