基于django-rest-framework的JWT的登陆与认证流程

基于django-rest-framework的JWT的登陆与认证流程

JWT(Json web token)的介绍 分析

基于django-rest-framework的登陆认证方式常用的大体可分为四种:
1. BasicAuthentication:账号密码登陆验证
2. SessionAuthentication:基于session机制会话验证
3. TokenAuthentication: 基于令牌的验证
4. JSONWebTokenAuthentication:基于Json-Web-Token的验证

其中最常用的是JWT(Json-Web-Token),如果对JWT不理解的推荐一篇文章:前后端分离之JWT用户认证

JWT具有以下优点:
1. 签名的方式验证用户信息,安全性较之一般的认证高
2. 加密后的字符串保存于客户端浏览器中,减少服务器存储压力
3. 签名字符串中存储了用户部分的非私密信息,一定程度上能够减少服务器数据库查询用户信息的开销

缺点:
1. 采用对称加密,一旦被恶意用户获取到加密方法,就可以不断破解入侵获取信息,不过基本加密方法很难被破解
2. 加大了服务器的计算开销,–不过相对于磁盘开销,这都不算啥
总的来说,JWT没多少去缺点,所以很多公司都用这个业务做用户认证,当然,涉及到金钱的,还是选择非对称加密方式比较好。

JWT在前后端的逻辑分析:
图:

django-rest-framework_jwt的使用

使用详情参考django-rest-framework_jwt.

  1. 安装rest-frame-work—jwt
pip install djangorestframework-jwt
  1. 配置settings文件的认证选择
REST_FRAMEWORK = {
    # 配置默认的认证方式 base:账号密码验证  
    #session:session_id认证
    'DEFAULT_AUTHENTICATION_CLASSES': (
        # drf的这一阶段主要是做验证,middleware的auth主要是设置session和user到request对象
        # 默认的验证是按照验证列表从上到下的验证
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        "rest_framework_jwt.authentication.JSONWebTokenAuthentication",
    )}
  1. 配置url(这里只针对做用户认证的)
from rest_framework_jwt.views import obtain_jwt_token
#...

urlpatterns = [
    # ...

    url(r'^api-token-auth/', obtain_jwt_token),
]

jwt在django-rest-framework中的实现原理

JWT实现的也是类似于session的一种会话保持机制,

登陆

用户在发起登陆请求的时候,相当于是给设定的”api-token-auth”这个url发起一个post请求,post的是两对键分别为”username”和”password”的json数据,url响应obtainJsonWebToken这个视图类,在这个视图内部定义了post方法去接受并处理数据。

这个视图类做了以下事情:
1. 序列化,将post过来的json数据转换成原生的python数据类型,序列化生成了JWT的token,并返回了user与token关联立的dict。

    return {
        'token': jwt_encode_handler(payload),
        'user': user
    }

2.序列化验证,并取出user和token值,生成响应体数据,然后实例化生成Response响应体对象:

    if serializer.is_valid():
        user = serializer.object.get('user') or request.user
        token = serializer.object.get('token')
        response_data = jwt_response_payload_handler(token, user, request)
        response = Response(response_data)

前端在接受到这个响应后,会将username及token加入到cookie中,这样就完成了登陆的全过程

验证

登陆过的用户,在访问api的时候,都会进行一次token的验证,会话机制就是这样的一个原理,保持联系的最基本的原理就是每次交互都进行一次验证。

在django中就会涉及到一个中间件系统,首先会依次响应django中间件,全局拦截请求,将前端发过来的request中的用户加入到django的request体中,以及将token加入到request的META体中(django对api接口过来的request进行了一次重新的封装,drf对django的request进行了再一次封装,都是基于中间件系统)

然后响应view的中间件,将token和user从request中取出,进行jwt_token的解密验证。

那么这样就实现了JWT的验证过程。

django 中间件系统

django项目的settings文件中一般会配置一个middleware的列表,也就是中间件列表,如下:

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    # 拦截请求,设置session到request
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    # 再次拦截请求,判断是否有session(上面已加入),设置user到request
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',]

一般而言,中间件就是一个类,继承自MiddlewareMixin,比如说SessionMiddleware:

class SessionMiddleware(MiddlewareMixin):
    def __init__(self, get_response=None):
        self.get_response = get_response
        engine = import_module(settings.SESSION_ENGINE)
        self.SessionStore = engine.SessionStore

    def process_request(self, request):
        session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME)
        request.session = self.SessionStore(session_key)

    def process_response(self, request, response):
        """
        If request.session was modified, or if the configuration is to save the
        session every time, save the changes and set a session cookie or delete
        the session cookie if the session has been emptied.

重载了两个方法,分别是process_request和process_response方法,相当于很多框架生命周期里面的钩子函数,这两个方法如果被重载了,那么在request/response的过程中,肯定会被执行,在可以选择自己需要的中间件,也可以自己定义中间件取实现不同的功能。一般而言,被用作全局拦截器使用。

猜你喜欢

转载自blog.csdn.net/Newbietan/article/details/80505403