登录接口设计和实现–Django播客系统(七)
用户登录接口设计
POST /users/login 用户登录
请求体 application/json
{
"password":"string",
"email":"string"
}
响应
200 登录成功
400 用户名密码错误
- 接收用户通过POST方法提交的登录信息,提交的数据是JSON格式数据
{
"password":"abc",
"email":"xdd@xdd.com"
}
- 从user表中email找出匹配的一条记录,验证密码是否正确
- 验证通过说明是合法用户登录,显示欢迎页面。
- 验证失败返回错误状态码,例如4xx
- 整个过程都采用AJAX异步过程,用户提交JSON数据,服务端获取数据后处理,返回JSON。
路由配置
from django.conf.urls import re_path
from .views import reg,login
urlpatterns = [
re_path(r'^$',reg),
re_path(r'^login$',login),
]
import jwt
import datetime
import bcrypt
from django.conf import settings
def jsonify(instance,allow=None,exclude=[]):
modelcls = type(instance)
if allow:
fn = (lambda x:x.name in allow)
else:
fn = (lambda x:x.name not in exclude)
return {
k.name:getattr(instance,k.name) for k in filter(fn,modelcls._meta.fields)}
def login(request:HttpRequest):
try:
payload = simplejson.loads(request.body)
print(payload)
email = payload["email"]
password = payload["password"]
user = User.objects.get(email=email)
print(user.password)
if bcrypt.checkpw(password,user.password.encode()):
token = gen_token(user.id)
res = JsonResponse({
"user":jsonify(user,exclude=["password"]),
"token":token
})
res.set_cookie("jwt",token)
return res
else:
return JsonResponse({
"error":"用户名或密码错误"},status=400)
except Exception as e:
print(e)
return JsonResponse({
"error":"用户名或密码错误"},status=400)
- 注册
- 登录验证
认证接口
- 如何获取浏览器提交的token信息?
- 使用Header中的Authorization
- 通过这个header增加token信息。
- 通过header发送数据,方法可以是Post、Get
- 自定义header
- 在Http请求头中使用X-JWT字段来发送token
- 本次选择第二种
认证流程
- 基本上所有的业务都有需要认证用户的信息。
- 在这里比较实际戳,如果过期,就直接抛未认证成功401,客户端收到后就改直接跳转到登录页。
- 如果没有提交user id,就直接重新登录。如果用户查到了,填充user对象。
- request->时间戳比较->user id比较->向后执行
Django的认证
- django.contrilb。auth中提供了许多方法,这里主要介绍其中的三个:
- authenticate(**credentials)
- 提供了用户认证,即验证用户名以及密码是否正确
- user = authentica(username=‘someone’,password=‘somepassword’)
- login(HttpRequest,user,backend=None)
- 该函数接受一个HttpRequest对象,以及一个认证了的User对象
- 此函数使用django的session框架给某个已认证的用户附加上session id等信息。
- logout(request)
- 注销用户
- 该函数接受一个HttpRequest对象,无返回值。
- 当调用该函数时,当前请求的session信息会全部清除
- 该用户即使没有登录,使用该函数也不会报错
- 还提供了一个装饰器来判断是否登录django.contrib.auth.decorators.login_required
- 本项目使用了无session机制,且用户信息自己建表管理,所以,认证需要自己实现。
中间件技术Middleware
- 官方定义,在Django的request和response处理过程中,由框架提供的hook钩子
- 中间技术在1.10后发生了改变,我们当前使用1.11版本,可以使用新的方式定义。
- 参考https://docs.djangoproject.com/en/1.11/topics/http/middleware/#writing-your-own-middleware
class SimpleMiddleware1:
def __init__(self,get_response):
self.get_response = get_response
def __call__(self