Django-用户功能设计与实现
文章目录
- 用户功能设计与实现
- 用户注册接口设计
- 路由设置
- CSRF处理
- 用户注册
- Django日志
- 配置
- 模型操作
- 管理器对象
- 查询
- 限制查询集
- 查询表达式
- Q对象
- 注册接口设计完善
- 认证
- 密码
- 重写reg
- 用户功能设计与实现
- 用户登录接口设计
- 认证
- 装饰器实现代码
- jwt过期
用户功能设计与实现
用户注册接口设计
接受用户通过post方法提交的注册信息。提交格式为json数据
检查email是否已存在与数据库表中,如果存在。返回错误状态码,不存在将用户提交的数据存入表中
整个过程是resful风格,前后端分离:必须约定好url和接口(各开发各的)
路由设置
from django.conf.urls import url,include
from django.contrib import admin
from django.http import HttpResponse,HttpRequest,JsonResponse
from django.template import loader
from django.template.backends.django import Template
from django.shortcuts import render #快捷方式def index(request): #这就是wsgi app的函数 只不过environ,start_response这两个参数给我们封装好了只需要request就行了# template:Template = loader.get_template('index.html')# print(type(template),'!!!!!',template.origin)# print(template.render({},request))return render(request,'index.html',{'a':['{}*{}={}'.format(i,j,i*j) for i in range(1,10) for j in range(1,10)],'b':list(range(1,10)),'d':list(range(10,20))})
from user.views import reg
urlpatterns = [url(r'^admin/', admin.site.urls), #管理后面 正则表达式(路劲) 后面视图函数url(r'^index',index), #首页url(r'^user/', include('user.urls')) #user目录下的子目录
]
将url/user/* 映射到user/的urls
user/urls.py
from django.conf.urls import url
from django.http import HttpResponse,HttpRequest,JsonResponse
from django.shortcuts import render #快捷方式
from user.views import regurlpatterns = [url(r'',reg)
]
user/views.py
from django.shortcuts import render
from django.http import HttpResponse,HttpRequest
# Create your views here.def reg(request:HttpRequest):return HttpResponse(b'user')
CSRF处理
这里我用的是postman,想做实验的可以下载
在post提交时,需给服务器发送一个csrf_token
解决方法有两个:
1.关闭中间件里的csrf验证(不推荐)
2.在模板的表单里加一个{% csrf_token %},它返回浏览器端会给cookie增加csrftoken字段,如果使用ajax进行post,需要在请求header中增加X-CSRFTOKEN
先用get请求index,获取csrftoken的值,在post的params里加入就可以访问成功了
先下载simplejson的包
pip install simplejson
from django.shortcuts import render
from django.http import HttpResponse,HttpRequest
import simplejson
# Create your views here.def reg(request:HttpRequest):# print(request.body)payload = simplejson.loads(request.body)print(payload)return HttpResponse(b'user')
postman发起请求
用户注册
from django.shortcuts import render
from django.http import HttpResponse,HttpRequest,HttpResponseBadRequest
import simplejson
from .models import User
# Create your views here.def reg(request:HttpRequest):try:# print(request.body)payload = simplejson.loads(request.body)email = payload['email']user = User.objects.filter(email=email)print(user.query)print(user,type(user))return HttpResponse(b'user')except Exception as e:print(e)return HttpResponseBadRequest('erro')
数据跟数据库内的用户比对
from django.shortcuts import render
from django.http import HttpResponse,HttpRequest,HttpResponseBadRequest
import simplejson
from .models import User
# Create your views here.def reg(request:HttpRequest):try:# print(request.body)payload = simplejson.loads(request.body)email = payload['email']#查询数据库比对邮箱是否唯一user = User.objects.filter(email=email)# print(user.query)# print(user,type(user))if user:return HttpResponseBadRequest()#没有邮箱name = payload['name']password= payload['payload']user = User()user.name = nameuser.email=emailuser.password = passworduser.save() #保存到数据库 django的model、save、update、delete会自动提交return HttpResponse(b'user')except Exception as e:print(e)return HttpResponseBadRequest('erro')
用户信息数据库加入成功
Django日志
配置
在官网文档查找logging 找到example复制到setting.py
模型操作
管理器对象
Django会给模型类提供一个objects对象,自己指定的话,django就不提供了
查询
def test(request:HttpRequest):qs = User.objects.all()print(type(qs))print([x for x in qs])print([x for x in qs])print(qs)print(qs)return HttpResponse()
查询会返回结果的集,是<class ‘django.db.models.query.QuerySet’>类型
它是惰性求值,和sqlalchemy一样
惰性求值:创建查询集不会带来任何数据库的访问,直到调用使用数据才会访问数据库
缓存:每一个查询集都包含一个缓存,接下来的查询集求值将使用缓存的结果
限制查询集
all | 所以默认limit 21 |
---|---|
filter | 过滤 返回满足条件的 |
exiude | 排除 where not value |
order_by | 排序,参数是字符串(order_by(‘-pk’)负号逆序) |
values | 返回一个对象字典的列表(查询语句后加,一般用于观察数据) |
返回单个值得方法
get | 返回满足条件的对象,没有找到抛出notexist异常,找到多个抛出multipleobjectreturned异常 |
---|---|
count | 返回当前查询的总条数 |
first | 返回第一个对象 |
exist | 判断查询集中是否有数据,有返回T |
last | 返回最后一个对象 |
查询表达式
查询表达式作为前面查询方法的参数
语法:属性名称__比较运算符=值
属性名和运算符之间使用双下划线
startwith,endwith | 开头结尾 |
---|---|
isnull,isnotnull | 是否为null |
contains | 包含,大小写敏感 |
exact,lt,gt,lte,gte | 等于,小于,大于,小于等于,大于等于 |
前面所的前面加i | 忽略大小写 |
in | 在什么范围 |
year,month,day,week_day,hour,minute,second | 日期处理 |
Q对象
Q对象,可以使用& ,|操作符来组成逻辑表达式,~表示not
from django.db.models import Q
def test(request:HttpRequest):qs = User.objects.filter(Q(id=1) |Q(id=2)).values()# print(type(qs))# print([x for x in qs])# print([x for x in qs])# print(qs)# print(qs)print(qs)return HttpResponse()
如果要混合关键字查询和Q对象,Q对象必须在关键字前面
注册接口设计完善
认证
HTTP协议是无状态协议,为了解决产生了cookies和session技术
传统的session-cookies机制,就是访问浏览器好哦偶浏览器给你一个session id,session中可以创建很多东西,服务器端保存大量的session信息
无session方案
浏览器需要一个id来表示身份还要保证客户端不可篡改信息
服务器端生成一个标识,并使用某种算法对标识签名
这方案的缺点是加密,解密需要消耗cpu计算资源,无法让浏览器自己主动检查过期的数据以清除,这技术叫JWT(JSON WEB token)
import jwtkey = '123456'payload = {'person':'hua'}x = jwt.encode(payload,key,'HS256')
print(x)header,payload,sig = x.split(b'.')
print(header)
print(payload)
print(sig)import base64def addequ(s):rest = 4-len(s)%4return s + b'='*restpayload = addequ(payload)
print(payload)
print(base64.urlsafe_b64decode(header))
print(base64.urlsafe_b64decode(payload))
print(base64.urlsafe_b64decode(addequ(sig)))
JWT就是用一个key加上数据用算法加密 得到header,数据,sig
浏览器将token发给成功登录的客户端,客户端请求上带着token,浏览器在用key计算和签名对比,一样,浏览器就认可
查看源码我们知道了JWT的全部过程 下面我们自己来实现JWT的加密过程
加载包,得到算法
得到key
得到signing_input
得到signature
总结:jwt生成都token为三部分:header,数据,签名
数据交换:使用私钥,密钥加密
密码
加盐,使用hash(password+salt)的结果存入数据库。随机加盐,增加了破解的难度
import bcryptpassword = b'123456'salt = bcrypt.gensalt()
x= bcrypt.hashpw(password,salt) #相同盐
y = bcrypt.hashpw(password,salt)
print(x,y,sep='\n')x= bcrypt.hashpw(password,bcrypt.gensalt()) #不同盐
y = bcrypt.hashpw(password,bcrypt.gensalt())
print(x,y,sep='\n')
重写reg
def reg(request:HttpRequest):try:# print(request.body)payload = simplejson.loads(request.body)email = payload['email']# print(email)#查询数据库比对邮箱是否唯一user = User.objects.filter(email=email)# print(user.query)# print(user,type(user))if user:return HttpResponseBadRequest()#没有邮箱name = payload['name']password= payload['password']password = bcrypt.hashpw(password.encode(),bcrypt.gensalt())# print(name,email,password)user = User()user.name = nameuser.email=emailuser.password = passworduser.save() #保存到数据库 django的model、save、update、delete会自动提交return JsonResponse({'token':get_token(user.id)})except Exception as e:print(e)return HttpResponseBadRequest('erro')
用户功能设计与实现
用户登录接口设计
def login(request:HttpRequest):# qs = User.objects.filter(Q(id=1) |Q(id=2)).values()# print(type(qs))# print([x for x in qs])# print([x for x in qs])# print(qs)# print(qs)try:payload = simplejson.loads(request.body)password = payload['password'].encode()email = payload['email']user = User.objects.get(email=email)#验证密码if bcrypt.checkpw(password,user.password.encode()):res = JsonResponse({'user':{'user_id':user.id,'name':user.name,'email':user.email,},'token':get_token(user.id)})res.set_cookie('jwt',get_token(user.id)) #token两种一个在json里 一个了可以setcookie 自己选方案return reselse:return HttpResponseBadRequest()except Exception as e:return HttpResponseBadRequest()
认证
如何获取浏览器的cookie信息?
1.使用header中的Authorization
2.自定义header:使用JWT字段发送token
class SimpleMiddleware(object):
def __init__(self,get_response):self.get_response = get_responsedef __call__(self,request):#request拦截处理#对header的jwt信息验证#<class 'django.core.handlers.wsgi.WSGIRequest'>print(type(request),'~~~~~~~~~')response = self.get_response(request)#response拦截处理return response
使用前先注册
装饰器实现代码
def authenticate(viewfunc):def wrapper(request:HttpRequest):# auth = request.META.get('HTTP_JWT')# if not auth:# return HttpResponse(status=401)# print((request.META['HTTP_JWT']))try:auth = request.META['HTTP_JWT']print('!!!!!!!!')payload= jwt.decode(auth,settings.SECRET_KEY, algorithms=[settings.ALG])print(payload,'~~~~~~~~~')user = User.objects.get(pk=payload['USER_ID'])#timestampcurrent = datetime.datetime.now().timestamp()delta = current - payload['TIMESTAMP']if delta> AUTH_EXPIRE or delta <= 0:print('+++++++++++++')return HttpResponse(status=401)except:return HttpResponse(status=401)ret = viewfunc(request)return retreturn wrapper@authenticate #auth验证用户身份,不通过返回401
def test(request):return HttpResponse(b'test ok')
jwt过期
jtw在payload中增加clamin exp。exp要求int整数的时间戳(到期时间)
import jwt
import datetime
import threading
key = '123456'
payload = {'person':'hua','exp':int(datetime.datetime.now().timestamp()) +10
}
x = jwt.encode(payload,key,'HS256')
print(1,jwt.get_unverified_header(x))
event = threading.Event()
try:while not event.wait(1):print(datetime.datetime.now().timestamp())jwt.decode(x,key,algorithms=['HS256'])
except Exception as e:print(e)
print(2,jwt.get_unverified_header(x))
Django-用户功能设计与实现相关推荐
- 用户功能设计与实现--Django播客系统(六)
用户功能设计与实现–Django播客系统(六) 文章目录 用户功能设计与实现--Django播客系统(六) 用户注册接口设计 路由配置 测试JSON数据 CSRF处理 JSON数据处理 错误处理 注册 ...
- django用户认证系统——注册3
用户注册就是创建用户对象,将用户的个人信息保存到数据库里.回顾一下 Django 的 MVT 经典开发流程,对用户注册功能来说,首先创建用户模型(M),这一步我们已经完成了.编写注册视图函数(V),并 ...
- django 用户管理相关的表
Django 用户管理相关的表: create table django_content_type (/*内容类型表*/id int(11) not null auto_increment,app_l ...
- django用户认证系统——拓展 User 模型2
Django 用户认证系统提供了一个内置的 User 对象,用于记录用户的用户名,密码等个人信息.对于 Django 内置的 User 模型, 仅包含以下一些主要的属性: username,即用户名 ...
- Python Django进阶教程(五)(session,Django用户认证)
Django版本:1.11 操作系统:Windows Python:3.5 欢迎加入学习交流QQ群:657341423 session(会话),Django用户认证. 每个网站都cookies,会话, ...
- Django 用户登陆访问限制 @login_required
#用户登陆访问限制 from django.http import HttpResponseRedirect#只有登录了才能看到页面 #设置方法一:指定特定管理员才能访问 def main(reque ...
- django用户认证系统——登录4
用户已经能够在我们的网站注册了,注册就是为了登录,接下来我们为用户提供登录功能.和注册不同的是,Django 已经为我们写好了登录功能的全部代码,我们不必像之前处理注册流程那样费劲了.只需几分钟的简单 ...
- python django用户登录系统_Django实现用户注册登录
学习Django中:试着着写一个用户注册登录系统,开始搞事情 =====O(∩_∩)O哈哈~===== ================= Ubuntu python 2.7.12 Django 1. ...
- python开发信息系统权限设置_python Django 用户管理和权限认证
Auth认证系统 from django.contrib.auth import login, logout, authenticate from django.contrib.auth.models ...
- django 用户授权与许可
在本教程中,我们将向您展示如何允许用户使用自己的帐户登录到您的网站,以及如何根据用户是否已登录及其权限来控制他们可以执行和查看的内容.作为演示的一部分,我们将扩展LocalLibrary网站,添加登录 ...
最新文章
- 【COGS】2287:[HZOI 2015]疯狂的机器人 FFT+卡特兰数+排列组合
- linux下configure命令详解
- 中国三大轴承厂是 哪三家?
- 知乎回答多线程爬虫案例
- C++确定字符串是否具有唯一字符的算法(附完整源码)
- PHP 5.3-5.5 新特性
- Java基础学习笔记三 Java基础语法
- Java基础-序列化和反序列化
- 一致 先验分布 后验分布_「分布式技术」分布式事务最终一致性解决方案,下篇...
- java解释器怎么写_Java解释器和编译器
- win10打开计算机黑屏怎么办,win10系统开机就一直黑屏无法进入桌面的解决方法...
- Html5视频播放代码
- matlab中值滤波器
- windows注册表恢复方法
- 谷歌中国六月过三关 研发团队已失七将
- 参观微软亚洲研究院有感
- jQuery学习笔记之closest()
- 服装企业ERP软件哪个公司好?施行服装ERP体系的要点是什么
- 【论文汇总】 ECCV 2020 语义分割paper汇总
- 图像配准(Image Registration)——深度学习方法