用户功能设计与实现–Django播客系统(六)
文章目录
- 提供用户注册处理
- 提供用户登录处理
- 提供路由配置
用户注册接口设计
- 接受用户通过Post方法提交的注册信息,提交的数据是JSON格式数据
- 检查email是否存在与数据库表中,如果存在返回错误状态码,例如4xx,如果不存在,将用户提交的数据存入表中
- 整个过程都采用AJAX异步过程,用户提交JSON数据,服务端获取数据后处理,返回JSON。
POST /users/ 创建用户
请求体 application/json
{
"password":"string",
"name":"string",
"email":"string"
}
响应
201 创建成功
400 请求数据错误
路由配置
- 为了避免项目中的urls.py条目过多,也为了让应用自己管理路由,采用多级路由
# djweb/urls.py文件
from django.urls import include
urlpatterns = [
path('admin/', admin.site.urls),
re_path(r'^$',index),
re_path(r'^index$',index),#不同路径可以指向同一个函数执行
re_path(r'^users/',include("user.urls")),
]
-
include函数参数写应用.路由模块,该函数就会动态导入指定的包的模块,从模块里面读取urlpatterns,返回三元组。
-
url函数第二参数如果不是可调用对象,如果是元组或列表,则会从路径中除去已匹配的部分,将剩余部分与应用中的路由模块的urlpatterns进行匹配。
-
新建
user/uls.py
文件
# user/uls.py
from django.conf.urls import re_path
from .views import reg
urlpatterns = [
re_path(r'^$',reg), #/users/
]
- 在
user/views.py
文件中添加reg方法
# user/views.py
from django.shortcuts import render
from django.http import HttpResponse,HttpRequest
def reg(request:HttpRequest):
return HttpResponse("user.reg")
- 浏览器中输入
http://127.0.0.1:8000/users/
测试(这是GET请求),可以看到响应的数据。下面开始完善视图函数。 - 在
user/views.py
中编写视图函数reg
测试JSON数据
-
使用POST方法,提交数据类型为application/json,json字符串要使用双引号。
-
这个数据是注册用的,由客户端提交。
- 数据提交模板为:
{ "password":"abc", "name":"xdd", "email":"xdd@xdd.com" }
- 可以使用Postman软件测试。
CSRF处理
-
在Post数据的时候,发现出现了下面的提示
- 原因:默认Django CsrfViewMiddleware中间件会对所有POST方法提交的信息做CSRF校验。
-
CSRF或XSRF(Cross-site Request Forgery),即跨站请求伪造。它也被称为:one click attack/session riding。是一种对网站的恶意利用。它伪造成来自受信任用户发起的请求,难以防范。
-
原理:
- 用户登录某网站A完成登录认证,网站返回敏感信息的Cookie,即使是会话级的Cookie
- 用户没有关闭浏览器,或认证的Cookie一段时间内不过期还持久化了,用户就访问攻击网站B
- 攻击网站B看似一切正常,但是某些页面里面有一些隐藏运行的代码,或者诱骗用户操作的按钮等
- 这些代码一旦运行就是悄悄地向网站A发起特殊请求,由于网站A的Cookie还有效,且访问的是网站A,则其Cookie就可以一并发给网站A
- 网站A看到这些Cookie就只能认为是登录用户发起的合理合法请求,就会执行
-
CSRF解决
-
关闭CSRF中间件(不推荐)
#djweb/settings.py MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', # 'django.middleware.csrf.CsrfViewMiddleware', #注释掉 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ]
-
csrftoken验证
- 在表单POST提交时,需要发给服务器一个csrf_token
- 模板中的表单Form中增加
{% csrf_token %}
,它返回到了浏览器端就会为cookie增加csrftoken字段,还会在表单中增加一个名为csrfiddlewaretoken隐藏控件<input type='hidden' name='csrfmiddlewaretoken' value='jZTxU0v5mPoLvugcfLbS1B6vT8COYrKuxMzodWv8oNAr3a4ouWlb5AaYG2tQi3dD' />
- POST提交表单数据时,需要将csrfmiddlewaretoken一并提交,Cookie中的csrf_token也一并会提交,最终在中间件中比较,相符通过,不相符就看到上面的403提示
-
双cookie验证
- 访问本站先获得csrftoken的cookie
- 如果使用AJAX进行POST,需要在每一次请求Header中增加自定义字段X-CSRFTOKEN,其值来自cookie中获取的csrftoken值
- 在服务端比较cookie和X-CSRFTOKEN中的csrftoken,相符通过
-
-
现在没有前端代码,为了测试方便,可以选择第一种方法先禁用中间件,测试完成后开启。
JSON数据处理
- simplejson标准库方便好用,功能强大。
pip install simplejson
- 浏览器端提交的数据放在了请求对象的body中,需要使用simplejson解析,解析的方式同Json模块,但是simplejson更方便。
错误处理
- Django中有很多异常类,定义在django.http下,这些类都继承自HttpResponse。
#user/views.py文件
from django.http import HttpResponse,HttpRequest,HttpResponseBadRequest,JsonResponse
import simplejson
def reg(request:HttpRequest):
print(request.POST)
print(request.body)
# print("- " * 30)
try:
payload = simplejson.loads(request.body)
email = payload['email']
name = payload['name']
password = payload["password"]
print(email,name,password)
return JsonResponse({
},status=201) #创建成功返回201
except Exception as e: #有任何异常,都返回
print(e)
return HttpResponseBadRequest() #这里返回实例,这不是异常类
- 将上面代码增加邮箱检查、用户信息保存功能,就要用到Django的模型操作。
- 本次采用Restful实践的设计,采用返回错误状态码+JSON错误信息方式。
注册代码 v1
# user/views.py文件
from django.http import HttpResponse,HttpRequest,HttpResponseBadRequest,JsonResponse
import simplejson
from .models import User
def reg(request:HttpRequest):
try:
payload = simplejson.loads(request.body)
email = payload['email']
query = User.objects.filter(email=email)
print(query)
print(query.query) #查看sQL语句
if query.first():
return JsonResponse({
"error":"用户已存在"}<