用django框架开发一个B2C购物网站用户注册知识点总结2
一:用户部分:
用户注册:
用户注册序列化器:
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的更多相关文章
- 用django框架开发一个B2C购物网站的基本流程和用到的知识点总结1
开发流程 开发模式采用前后端分离模式,作为后端开发人员我们只关注后端业务逻辑开发: 省略项目框架搭建文件的配置部分.... 一:用户部分 在项目开发中我们要用到用户模型类User,Django认证系统 ...
- 基于django快速开发一个网站(一)
基于django快速开发一个网站(一) * 创建虚拟环境.基于虚拟环境创建django==2.0.0和图片加载库和mysql数据库驱动 1. 创建目录并创建虚拟环境 ╰$ mkdir Cornuco ...
- 基于Spring+Spring MVC+Mybatis的B2C购物网站
代码地址如下:http://www.demodashi.com/demo/12935.html 准备工作 当前项目运行的系统环境是MacOS,已经测试可以正常运行,并且之前开发的时候也在Windows ...
- YII框架开发一个项目的通用目录结构
YII框架开发一个项目的通用目录结构: 3 testdrive/ 4 index.php Web 应用入口脚本文件 5 assets/ 包含公开的资源文件 6 css/ 包含 CSS 文件 7 ima ...
- 使用Phalcon框架开发一个简易的博客系统
使用Phalcon PHP框架开发一个简易的博客系统(类似于CMS) 最近在做Phalcon(Phalcon在英文中指的是鸟类中飞得最快的那一个物种,由于是高性能框架,借用了这个词)相关的项目,由于刚 ...
- php怎么做网站?如何用PHP开发一个完整的网站?
1.PHPer应具备的知识 (1)PHP知识: 熟练掌握基础函数,PHP语句(条件.循环),数组(排序.读取),函数(内部 构造),运算(数学 逻辑),面向对象(继承 接口 封装 多态静态属性)等. ...
- jQuery框架开发一个最简单的幻灯效果
在线演示 在这个课程中,我们将介绍如何使用jQuery来开发一个最简单的图片幻灯效果. 立刻观看互动课程:jQuery框架开发一个最简单的幻灯效果 阅读原文:jQuery框架开发一个最简单的幻灯效果
- 第六模块:WEB框架开发 第1章·Django框架开发88~128
88-Ajax简介 89-Ajax的简单实现 90-基于Ajax的传递数据 91-基于Ajax的登录验证 92-基于Form表单的文件上传 93-请求头之contentType 94-Ajax传递js ...
- 第六模块: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 ...
随机推荐
- Spark学习体系整理(基础篇、中级篇、高级篇所涉及内容)
新手刚开始学习比较迷茫,参考下面,然后找相关资料学习 1 Spark基础篇 1.1 Spark生态和安装部署 在安装过程中,理解其基本操作步骤. 安装部署 ...
- Linux驱动程序接口
§1. Linux驱动程序接口 系统调用是操作系统内核与应用程序之间的接口,设备驱动程序则是操作系统内核与机器硬件的接口.几乎所有的系统操作最终映射到物理设备,除了CPU.内存和少数其它设备,所有的设 ...
- win32 去掉窗口边框
参考:http://www.blitzbasic.com/Community/posts.php?topic=67222 Strict Graphics 320, 200 SetClsColor 0, ...
- docker 镜像导入导出[转]
0)查看镜像id sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE quay.io/calico/node v1.0.1 c70511a4 ...
- vs2017 xamarin导入jar,SO文件的问题
最近要弄用vs弄个安卓的系统,因为要使用硬件,所以要引进jar,SO文件 导入jar文件很顺利,具体步骤我也是在网上找的这里给个链接 http://www.2cto.com/kf/201604/502 ...
- 请求MWS报错401:Access Denied
跑MWS接口,报错: Caught Exception: Access denied Response Status Code: Error Code: AccessDenied Error Type ...
- Linux make menuconfig报错 Your display is too small to run Menuconfig!
在没有全屏的状态下执行 make menuconfig,如果报下面的错误,表示终端的窗口太小,需要放大窗口或者全屏操作. ## using defaults found in /dev/null#Yo ...
- CentOS 7 named设置主从复制
前两篇文章介绍了named的安装和配置forward. 本文将介绍named的主从复制. 在从named的配置中添加: zone "weiheng.ink" IN { type s ...
- python set集合 以及 深浅拷贝
set集合 特点: 无序, 不重复, 元素必须可哈希(不可变) 作用: 去重复 本身是可变的数据类型. 有增删改查操作. frozenset()冻结的集合. 不可变的. 可hash的 深浅拷贝() 1 ...
- NFV网络功能虚拟化 基本概念
NFV基本概念 NFV则由运营商联盟提出,为了加速部署新的网络服务,运营商倾向于放弃笨重昂贵的专用网络设备,转而使用标准的IT虚拟化技术来拆分网络功能模块,如DNS.NAT.Firewall等.于是一 ...