一:用户部分:

用户注册:

用户注册序列化器:

 import re

 from django_redis import get_redis_connection
from rest_framework import serializers from users.models import User class CreateUserSerializer(serializers.ModelSerializer):
"""创建用户序列化器类"""
password2 = serializers.CharField(label='重复密码', write_only=True)
sms_code = serializers.CharField(label='短信验证码', write_only=True)
allow = serializers.CharField(label='是否同意协议', write_only=True)
token = serializers.CharField(label='JWT Token', read_only=True) class Meta:
model = User
fields = ('id', 'username', 'password', 'mobile', 'password2', 'sms_code', 'allow', 'token') extra_kwargs = {
'username': {
'min_length': 5,
'max_length': 20,
'error_messages': {
'min_length': '仅允许5-20个字符的用户名',
'max_length': '仅允许5-20个字符的用户名',
}
},
'password': {
'write_only': True,
'min_length': 8,
'max_length': 20,
'error_messages': {
'min_length': '仅允许8-20个字符的密码',
'max_length': '仅允许8-20个字符的密码',
}
}
} # (参数完整性,手机号格式,手机号是否已注册,是否同意协议,两次密码是否一致,短信验证码是否正确)
def validate_username(self, value):
"""用户名不能是纯数字"""
if re.match(r'^\d+$', value):
raise serializers.ValidationError('用户名不能都是数字') return value def validate_mobile(self, value):
"""手机号格式,手机号是否已注册"""
# 手机号格式
if not re.match(r'^1[3-9]\d{9}$', value):
raise serializers.ValidationError('手机号格式不正确') # 手机号是否已注册
count = User.objects.filter(mobile=value).count()
if count > 0:
raise serializers.ValidationError('手机号已存在') return value def validate_allow(self, value):
"""是否同意协议"""
if value != 'true':
raise serializers.ValidationError('请同意协议')
return value def validate(self, attrs):
"""两次密码是否一致,短信验证码是否正确"""
# 两次密码是否一致
password = attrs['password']
password2 = attrs['password2'] if password != password2:
raise serializers.ValidationError('两次密码不一致') # 短信验证码是否正确
# 获取真实的短信验证码内容
mobile = attrs['mobile']
redis_conn = get_redis_connection('verify_codes')
real_sms_code = redis_conn.get('sms_%s' % mobile) # bytes if not real_sms_code:
raise serializers.ValidationError('短信验证码已过期') # 对比
sms_code = attrs['sms_code'] # str
real_sms_code = real_sms_code.decode() # str
if sms_code != real_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'] # # 调用父类create方法
# user = super().create(validated_data)
#
# # 对密码进行加密
# password = validated_data['password']
# user.set_password(password)
# user.save() # 调用create_user方法
user = User.objects.create_user(**validated_data) # 注册成功就让用户处于登录状态
# 由服务器签发一个jwt token,保存用户身份信息
from rest_framework_jwt.settings import api_settings jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER # 生成载荷信息(payload)
payload = jwt_payload_handler(user)
# 生成jwt token
token = jwt_encode_handler(payload) # 给user对象增加一个属性token,保存jwt token信息
user.token = token # 返回user
return user
对应视图函数:
 from django.shortcuts import render
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.generics import GenericAPIView, CreateAPIView from users.models import User
from users.serializers import CreateUserSerializer
# Create your views here. # POST /users/
# class UserView(GenericAPIView):
class UserView(CreateAPIView):
serializer_class = CreateUserSerializer # def post(self, request):
# """
# 注册用户信息的保存:
# 1. 获取参数并进行校验(参数完整性,两次密码是否一致,手机号格式,手机号是否已注册,短信验证码是否正确,是否同意协议)
# 2. 保存注册用户信息
# 3. 返回应答,注册成功
# """
# # 1. 获取参数并进行校验(参数完整性,两次密码是否一致,手机号格式,手机号是否已注册,短信验证码是否正确,是否同意协议)
# serializer = self.get_serializer(data=request.data)
# serializer.is_valid(raise_exception=True)
#
# # 2. 保存注册用户信息(create)
# serializer.save()
#
# # 3. 返回应答,注册成功
# return Response(serializer.data, status=status.HTTP_201_CREATED) # url(r'^usernames/(?P<username>\w{5,20})/count/$', views.UsernameCountView.as_view()),
class UsernameCountView(APIView):
"""
用户名数量
"""
def get(self, request, username):
"""
获取指定用户名数量
"""
count = User.objects.filter(username=username).count() data = {
'username': username,
'count': count
} return Response(data) # url(r'^mobiles/(?P<mobile>1[3-9]\d{9})/count/$', views.MobileCountView.as_view()),
class MobileCountView(APIView):
"""
手机号数量
"""
def get(self, request, mobile):
"""
获取指定手机号数量
"""
count = User.objects.filter(mobile=mobile).count() data = {
'mobile': mobile,
'count': count
} return Response(data)

用到的知识点:

##### 2. JWT token

1)session认证

```python
1. 接收用户名和密码
2. 判断用户名和密码是否正确
3. 保存用户的登录状态(session)
session['user_id'] = 1
session['username'] = 'smart'
session['mobile'] = ''
4. 返回应答,登录成功
``` session认证的一些问题: > 1. session存储在服务器端,如果登录的用户过多,服务器开销比较大。
> 2. session依赖于cookie,session的标识存在cookie中,可能会有CSRF(跨站请求伪造)。 2)jwt 认证机制(替代session认证) ```
1. 接收用户名和密码
2. 判断用户名和密码是否正确
3. 生成(签发)一个jwt token(token中保存用户的身份信息) 公安局(服务器)=>签发身份证(jwt token)
4. 返回应答,将jwt token信息返回给客户端。
``` 如果之后需要进行身份认证,客户端需要将jwt token发送给服务器,由服务器验证jwt token的有效性。 3)jwt 的数据格式 ```
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ik
pvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFO
``` a)headers头部 ```
{
"token类型声明",
"加密算法"
}
``` base64加密(很容易被解密) b)payload(载荷):用来保存有效信息 ```
{
"user_id": 1,
"username": "smart",
"mobile": "",
"exp": "有效时间"
}
``` base64加密 c)signature(签名):防止jwt token被伪造 将headers和payload进行拼接,用.隔开,使用一个密钥(secret key)进行加密,加密之后的内容就是签名。 jwt token是由服务器生成,密钥保存在服务器端。 ##### 3. jwt 扩展签发jwt token
from rest_framework_jwt.settings import api_settings

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)

 

用django框架开发一个B2C购物网站用户注册知识点总结2的更多相关文章

  1. 用django框架开发一个B2C购物网站的基本流程和用到的知识点总结1

    开发流程 开发模式采用前后端分离模式,作为后端开发人员我们只关注后端业务逻辑开发: 省略项目框架搭建文件的配置部分.... 一:用户部分 在项目开发中我们要用到用户模型类User,Django认证系统 ...

  2. 基于django快速开发一个网站(一)

    基于django快速开发一个网站(一) *  创建虚拟环境.基于虚拟环境创建django==2.0.0和图片加载库和mysql数据库驱动 1. 创建目录并创建虚拟环境 ╰$ mkdir Cornuco ...

  3. 基于Spring+Spring MVC+Mybatis的B2C购物网站

    代码地址如下:http://www.demodashi.com/demo/12935.html 准备工作 当前项目运行的系统环境是MacOS,已经测试可以正常运行,并且之前开发的时候也在Windows ...

  4. YII框架开发一个项目的通用目录结构

    YII框架开发一个项目的通用目录结构: 3 testdrive/ 4 index.php Web 应用入口脚本文件 5 assets/ 包含公开的资源文件 6 css/ 包含 CSS 文件 7 ima ...

  5. 使用Phalcon框架开发一个简易的博客系统

    使用Phalcon PHP框架开发一个简易的博客系统(类似于CMS) 最近在做Phalcon(Phalcon在英文中指的是鸟类中飞得最快的那一个物种,由于是高性能框架,借用了这个词)相关的项目,由于刚 ...

  6. php怎么做网站?如何用PHP开发一个完整的网站?

    1.PHPer应具备的知识 (1)PHP知识: 熟练掌握基础函数,PHP语句(条件.循环),数组(排序.读取),函数(内部 构造),运算(数学 逻辑),面向对象(继承 接口 封装 多态静态属性)等. ...

  7. jQuery框架开发一个最简单的幻灯效果

    在线演示 在这个课程中,我们将介绍如何使用jQuery来开发一个最简单的图片幻灯效果. 立刻观看互动课程:jQuery框架开发一个最简单的幻灯效果 阅读原文:jQuery框架开发一个最简单的幻灯效果

  8. 第六模块:WEB框架开发 第1章·Django框架开发88~128

    88-Ajax简介 89-Ajax的简单实现 90-基于Ajax的传递数据 91-基于Ajax的登录验证 92-基于Form表单的文件上传 93-请求头之contentType 94-Ajax传递js ...

  9. 第六模块:WEB框架开发 第1章·Django框架开发1~50

    01-Django基础介绍 02-Web应用程序1 03-Web应用程序2 04-http请求协议1 05-http请求协议2 06-http协议之响应协议 07-wsgire模块1 08-wsgir ...

随机推荐

  1. python 正则表达式字符说明

    . 元字符 说明 . 代表任意字符 | 逻辑或操作符 [ ] 匹配内部的任一字符或子表达式 [^] 对字符集和取非 - 定义一个区间 \ 对下一字符取非(通常是普通变特殊,特殊变普通) * 匹配前面的 ...

  2. 《DSP using MATLAB》示例Example6.18、6.19

  3. 算法导论进度帖startedby20131029

    2013.10.29 今天开始啃难啃的算法导论,俗一点说,光阴似箭,剩下的时间已经不多了,所以开始好好奋进吧~ 第一章翻过去了,对附录中的数学基础再补看一遍,发现很多东西其实掌握的都很薄弱的,附录A的 ...

  4. salesforce 公开网页,免登陆

    設定→カスタマイズ→コミュニテ→新建一个visfualforce的コミュニテ ビルド->カスタマイズ->コミュニティ->すべてのコミュニティ->新規コミュニティ 然后选中新规的 ...

  5. wpf中如何在xaml中绑定cs中类的属性

    cs代码:/// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class MainWin ...

  6. 日志框架--(二)JDK Logging

    前言 从jdk1.4起,JDK开始自带一套日志系统.JDK Logger最大的优点就是不需要任何类库的支持,只要有Java的运行环境就可以使用.相对于其他的日志框架,JDK自带的日志可谓是鸡肋,无论易 ...

  7. Android中执行的错误:java.lang.UnsatisfiedLinkError: Couldn't load locSDK3: findLibrary returned null.

    今天在使用百度地图的时候执行发现报错: 明明已经增加了liblocSDK3.so.但总是无法定位.提示错误java.lang.UnsatisfiedLinkError: Couldn't load l ...

  8. 笔记:配置 webpack dev server

    笔记:配置 webpack dev server 安装 webpack-dev-server 组件 配置 webpack.config.js 配置 增加 html-webpack-plugin 组件 ...

  9. Maven使用中的常见问题整理

    1.更新eclipse的classpath加入新依赖  1.在dependencyManagement里面加入包括版本在内的依赖信息,如: <dependency> <groupId ...

  10. Python2 和 Python3 的区别(待完善)

    1.宏观上 python2 :源码不标准,混乱,重复代码太多 python3 :统一 标准,去除重复代码. 2. print python2 :括号可有可无 print(a)  或  print ap ...