日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

非常详细的Django使用Token(转)

發(fā)布時間:2023/11/29 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 非常详细的Django使用Token(转) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

基于Token的身份驗證

在實現(xiàn)登錄功能的時候,正常的B/S應(yīng)用都會使用cookie+session的方式來做身份驗證,后臺直接向cookie中寫數(shù)據(jù),但是由于移動端的存在,移動端是沒有cookie機(jī)制的,所以使用token可以實現(xiàn)移動端和客戶端的token通信。

驗證流程

整個基于Token的驗證流程如下:

  • 客戶端使用用戶名跟密碼請求登錄
  • 服務(wù)器收到請求,去驗證用戶名和密碼
  • 驗證成功后,服務(wù)端會簽發(fā)一個Token,再把這個Token發(fā)送到客戶端
  • 客戶端收到的Token以后可以把它存儲起來,比如放在Cookie或LocalStorage里
  • 客戶端每次向服務(wù)器發(fā)送其他請求的時候都要帶著服務(wù)器簽發(fā)的Token
  • 服務(wù)器收到請求,去驗證客戶端請求里面帶著的Token,如果驗證成功,就像客戶端返回請求的數(shù)據(jù)
  • JWT

    構(gòu)造Token的方法挺多的,可以說只要是客戶端和服務(wù)器端約定好了格式,是想怎么寫就怎么寫的,然而還有一些標(biāo)準(zhǔn)寫法,例如JWT讀作/jot/,表示:JSON Web Tokens.
    JWT標(biāo)準(zhǔn)的Token有三個部分:

    • header
    • payload
    • signature
      三個部分會用點分割開,并且都會使用Base64編碼,所以真正的Token看起來像這樣
    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJuaW5naGFvLm5ldCIsImV4cCI6IjE0Mzg5NTU0NDUiLCJuYW1lIjoid2FuZ2hhbyIsImFkbWluIjp0cnVlfQ.SwyHTEx_RQppr97g4J5lKXtabJecpejuef8AqKYMAJc

    Header

    header部分主要是兩部分內(nèi)容,一個是Token的類型,另一個是使用的算法,比如下面的類型就是JWT,使用的算法是HS256:

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

    上面的內(nèi)容要用 Base64 的形式編碼一下,所以就變成這樣:

    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

    Payload

    Payload 里面是 Token 的具體內(nèi)容,這些內(nèi)容里面有一些是標(biāo)準(zhǔn)字段,你也可以添加其它需要的內(nèi)容。下面是標(biāo)準(zhǔn)字段:

    • iss:Issuer,發(fā)行者
    • sub:Subject,主題
    • aud:Audience,觀眾
    • exp:Expiration time,過期時間
    • nbf:Not before
    • iat:Issued at,發(fā)行時間
    • jti:JWT ID

    Signature

    JWT的最后一部分是Signature,這部分相當(dāng)于前兩段的摘要,用來防止其他人來篡改Token中的信息,在處理時可以首先將前兩段生成的內(nèi)容使用Base64生成一下再加鹽然后利用MD5等摘要算法在生成一遍

    服務(wù)端生成Token

    在服務(wù)端生成Token的時候,需要解決兩個問題

  • 使用什么加密算法
  • Token如何存儲
  • 加密算法

    這里的加密算法并不是MD5,SHA1這樣的哈希算法,因為這種算法是無法解密的,只能用來生成摘要,在Django中內(nèi)置了一個加密前面模塊django.core.signing模塊,可以用來加密和解密任何數(shù)據(jù),使用簽名模塊的dumps和load函數(shù)來實現(xiàn)

    示例:

    from django.core import signing value = signing.dumps({"foo":"bar"}) src = signing.loads(value) print(value) print(src)

    結(jié)果:

    eyJmb28iOiJiYXIifQ:1NMg1b:zGcDE4-TCkaeGzLeW9UQwZesciI {‘foo’: ‘bar’}

    Token如何存儲

    用什么存儲

    在服務(wù)器中Token可以存儲在內(nèi)存中,因為本質(zhì)是字符串,所以并不會占用很大的內(nèi)存空間,如果是分布式的存儲可以將所有的token信息分段存儲在不同的服務(wù)器中,也可以存儲在數(shù)據(jù)庫中,在Django中提供了緩存類,可以用來存儲Token,Django的緩存可以結(jié)合Redis來使用,可以借助django-redis來實現(xiàn)

    安裝

    pip install django-redis

    配置

    為了使用django-redis,需要將django cache setting修改,修改settings.py,默認(rèn)是沒有Cache的配置信息的,在其中添加:

    CACHES = {"default": {"BACKEND": "django_redis.cache.RedisCache","LOCATION": "redis://127.0.0.1:6379","OPTIONS": {"CLIENT_CLASS": "django_redis.client.DefaultClient",}} }

    當(dāng)然,需要你首先安裝了redis

    cache使用

    cache使用的時候基本可以使用set和get方法來進(jìn)行存/取數(shù)據(jù)

    >>> cache.set('my_key', 'hello, world!', 30) >>> cache.get('my_key') 'hello, world!'

    如何存

    由于redis是使用k-v模式來進(jìn)行存儲數(shù)據(jù)的,我們可以使用用戶名作為key,而token信息作為value,相較于直接使用token作為key的方式,好處是我們可以使用更少的空間實現(xiàn)一些功能,例如當(dāng)用戶修改了密碼或點擊注銷之后,它的token可以直接失效,直接將該用戶名所對應(yīng)的數(shù)據(jù)刪除就好了,或者用戶在一次登錄成功后,又一次請求了登錄接口,我們可以很簡單的更新該用戶的token信息,而這樣存儲所依賴于我們的token可以進(jìn)行解密,如果你是直接生成了一串無法解密的數(shù)據(jù)作為token,不能使用用戶名作為token了

    code

    import time from django.core import signing import hashlib from django.core.cache import cacheHEADER = {'typ': 'JWP', 'alg': 'default'} KEY = 'CHEN_FENG_YAO' SALT = 'www.lanou3g.com' TIME_OUT = 30 * 60 # 30mindef encrypt(obj):"""加密"""value = signing.dumps(obj, key=KEY, salt=SALT)value = signing.b64_encode(value.encode()).decode()return valuedef decrypt(src):"""解密"""src = signing.b64_decode(src.encode()).decode()raw = signing.loads(src, key=KEY, salt=SALT)print(type(raw))return rawdef create_token(username):"""生成token信息"""# 1. 加密頭信息header = encrypt(HEADER)# 2. 構(gòu)造Payloadpayload = {"username": username, "iat": time.time()}payload = encrypt(payload)# 3. 生成簽名md5 = hashlib.md5()md5.update(("%s.%s" % (header, payload)).encode())signature = md5.hexdigest()token = "%s.%s.%s" % (header, payload, signature)# 存儲到緩存中cache.set(username, token, TIME_OUT)return tokendef get_payload(token):payload = str(token).split('.')[1]payload = decrypt(payload)return payload# 通過token獲取用戶名 def get_username(token):payload = get_payload(token)return payload['username']passdef check_token(token):username = get_username(token)last_token = cache.get(username)if last_token:return last_token == tokenreturn False

    轉(zhuǎn)載于:https://www.cnblogs.com/Paul-watermelon/p/11286698.html

    總結(jié)

    以上是生活随笔為你收集整理的非常详细的Django使用Token(转)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。