django restframework jwt

既然要来学习jwt(json web token),那么咱们确定是先要了解jwt的优点以及应用场景--跨域认证。python

 

$ pip install djangorestframework-jwt

  

传统cookie-session认证步骤:

一、用户向服务器发送用户名和密码。web

二、服务器验证经过后,在当前对话(session)里面保存相关数据,好比用户角色、登陆时间等等。django

在django session表中,session_key,session_data,expire_date.其中session_data保存的是base64编码后的用户对象。json

import base64

r = base64.b64decode("NDQ3OGI4MDA3YTI3MzM2NTQ5ZjhhZGZhNzM0ZjM2OWNlOTFmYWQ0ODp7Il9hdXRoX3VzZXJfaWQiOiIxIiwiX2F1dGhfdXNlcl9iYWNrZW5kIjoiZGphbmdvLmNvbnRyaWIuYXV0aC5iYWNrZW5kcy5Nb2RlbEJhY2tlbmQiLCJfYXV0aF91c2VyX2hhc2giOiIyOTBkMjY0YzY3MmMyYmNjZWFiZDRkZWJlZGJjMmQyM2QzNzI5YjBkIn0=")
print(r)

>>>
b'4478b8007a27336549f8adfa734f369ce91fad48:{"_auth_user_id":"1","_auth_user_backend":"django.contrib.auth.backends.ModelBackend","_auth_user_hash":"290d264c672c2bcceabd4debedbc2d23d3729b0d"}'

   

三、服务器向用户返回一个 session_id,写入用户的 Cookie。后端

四、用户随后的每一次请求,都会经过 Cookie,将 session_id 传回服务器。api

五、服务器收到 session_id,找到前期保存的数据,由此得知用户的身份。跨域

 

这种模式的问题在于,扩展性很差。单机固然没有问题,若是是服务器集群,或者是跨域的服务导向架构,就要求 session 数据共享,每台服务器都可以读取 session。服务器

 

jwt原理

由header,payload,signature三个部分组成cookie

举个栗子session

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VybmFtZSI6InJvb3QiLCJleHAiOjE1NTI5NzE5ODIsImVtYWlsIjoiMTc4NTg4MDQyNjRAMTYzLmNvbSJ9.KuZq40SkiEz9La1wzXy20irjbckNJ0SNWq2EvXBwf0A

 每部分由.分隔,其中header和payload可由base64直接decode可得

header

{"typ":"JWT","alg":"HS256"}

payload

用户信息,django中取决于UserProfile,UserProfileSerializer

signature

对前两部分的签名,防止数据被篡改。指定一个密钥,使用header中的加密方式

token = base64.b64encode(bytes_header)+"."+base64.b64encode(bytes_payload)+"."+secret

 

django restframework jwt 集成

settings.py

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication',
    ),
}

JWT_AUTH = {
    # 指明token的有效期
    'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),
}

  

  • BasicAuthentication

该认证方案使用 HTTP Basic Authentication,并根据用户的用户名和密码进行签名。Basic Authentication 一般只适用于测试。

  • SessionAuthentication

此认证方案使用 Django 的默认 session 后端进行认证。Session 身份验证适用于与您的网站在同一会话环境中运行的 AJAX 客户端。

urls.py

from rest_framework_jwt.views import obtain_jwt_token


urlpatterns = [
    # ...
    url(r'^api-token-auth/', obtain_jwt_token),
]

  

集成完后的测试代码

import json

import requests


# 验证jwt
url = "http://127.0.0.1:8000/api-token-auth/?format=json"
data = {
    "username": "root",
    "password": "Admin123."
}
# data = json.dumps(data)
res = requests.post(url,data=data)
token = res.text
print("token:",token)

token = json.loads(token).get("token")
user_url = "http://127.0.0.1:8000/users/?format=json"
headers = {
    "Authorization":"JWT "+ token
}
res = requests.get(user_url,headers=headers)
print(res.text)

  

本身实现jwt也很是简单

1) base64加HS256 手写token

2) middleware 验证token

上述1和2的传递是经过request参数,验证成功后只须要咱们赋予request.user 一个user对象便可。

相关文章
相关标签/搜索