• django restframework jwt


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

    $ pip install djangorestframework-jwt
    

      

    传统cookie-session认证步骤:

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

    2、服务器验证通过后,在当前对话(session)里面保存相关数据,比如用户角色、登录时间等等。

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

    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"}'
    

       

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

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

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

    这种模式的问题在于,扩展性不好。单机当然没有问题,如果是服务器集群,或者是跨域的服务导向架构,就要求 session 数据共享,每台服务器都能够读取 session。

    jwt原理

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

    举个栗子

    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对象即可。

  • 相关阅读:
    C# 重绘图片.图片加字,加矩形,加圆,加线,根据XY坐标修改RGB
    Net5 WorkService 继承 Quarzt 以及 Net5处理文件上传
    select高级用法之各种连接
    mysqladmin客户端命令详解
    Mysql 配置文件管理
    kubeadm 部署的etcd集群管理
    数据库客户连接管理及配置文件
    Mysql 用户创建及授权管理
    在k8s 1.19+版本中部署traefik 2.X版本 ingress控制器
    JS 关闭页面窗口通用方法,兼容各个浏览器
  • 原文地址:https://www.cnblogs.com/zenan/p/10552683.html
Copyright © 2020-2023  润新知