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. Go语言之闭包

    闭包的最初目的是为了减少全局变量,在函数调用过程中,隐式的传递共享变量. 但这样的编辑,带来的坏处是不够直接清晰. 所以,如非必要,不要使用. 对象是附有行为的数据,它在类中集中定义, 而闭包是附有数 ...

  2. docker挂载点泄露问题

    本来以为我不会遇到. 结果还是遇到了. 现象为k8s delete pod时,系统一直显示Terminatiing,无论多久都不能正常. 以下两个帖子大概说明了是怎么回事. https://blog. ...

  3. 关于浏览器对html, js,css的解析先后顺序的理解

    1.首先要了解页面的结构(包含哪些元素?哪些计算机语言能够在页面中运行 ) (1)html          不仅可以包含文字,还可以包含图片.链接,甚至音乐.程序等非文字元素的标记语言       ...

  4. stl测试

    以下测试都在学校电脑进行 我觉得应该比考试机器慢一点.. 1.map map的速度测出来和放入数值大小有很大关系 比如 #include <bits/stdc++.h> using nam ...

  5. 【Android】Android 监听apk安装替换卸载广播

    [Android]Android 监听apk安装替换卸载广播 首先是要获取应用的安装状态,通过广播的形式 以下是和应用程序相关的Broadcast Action ACTION_PACKAGE_ADDE ...

  6. Docker 二进制安装docker

    https://blog.csdn.net/bruce_yds/article/details/80035714

  7. 防止vs编译时自动启动单元测试

    Tools → Options → Live Unit Testing   Pause 勾选

  8. 20165235 祁瑛 2018-4 《Java程序设计》第六周学习总结

    20165235 祁瑛 2018-4 <Java程序设计>第六周学习总结 教材学习内容总结 常用实用类 (一)1.String类是final类型的,String类型常量也是对象.2.可以使 ...

  9. ELM:ELM基于近红外光谱的汽油测试集辛烷值含量预测结果对比—Jason niu

    %ELM:ELM基于近红外光谱的汽油测试集辛烷值含量预测结果对比—Jason niu load spectra_data.mat temp = randperm(size(NIR,1)); P_tra ...

  10. python3 在 windows 读取路径多了一个\u202a 是咋回

    python3 在 windows 读取路径多了一个\u202a 是咋回事