2019年7月1日 星期一

Python Token sample


Token vs Cookie

流程差不多,差別在Cookie 是在第一次response 時代有set cookie 的訊息;Token 則是回傳一連串的字符
但Token 多了兩個優勢,讓他的scalability 更好
  • 無狀態:Token 不需要保存session,一切以Token 反計算判斷身分,Token 本身通常帶有時間性
  • 可以多裝置多網域:呈上,Token 是用計算的方式判斷身分,所以使用API 跟取得Token 的Server 只要共享用戶資料就行


Python module:itsdangerous  https://itsdangerous.readthedocs.io/en/latest/

itsdangerous  提供多種簽名或序列化的物件
  • Signing : 在string 後面加亂數簽章
  • Timestamp Signing :同上,但是有時效性
  • Serialization :Signing 只能針對字串,Serialization  則不限
  • Timestamp Serialization :同上,但是有時效性
  • URL Safe Serialization : 有別於前面的,會保留原內容再外加簽章,此物件只會產生簽章
  • JSON Web Signature:是一種常用的Token 標準,將JSON 物件 隱含在簽章內,通常稱為JWT (JSON Web Token)
  • Timestamp JSON Web Signature:同上,但是有時效性


JWT

由header、payload、Signature 組成,如下
eyJhbGciOiJIUzI1NiJ9 表header,表示使用的演算法
eyJ4Ijo0Mn0 表{"X":42}
ZdTn1YyGz9Yx5B5wNpWRL221G1WpVE5fPCPKNuc6UAo 簽章,搭配secret key 任一字串讓server 匹配檢查用
from itsdangerous import JSONWebSignatureSerializer
= JSONWebSignatureSerializer("secret-key")
s.dumps({"x"42})
'eyJhbGciOiJIUzI1NiJ9.eyJ4Ijo0Mn0.ZdTn1YyGz9Yx5B5wNpWRL221G1WpVE5fPCPKNuc6UAo'

若使用JWT,將帳號資料代入payload,則產生的token 就可以在有相同帳號資料的Server 使用

以下有個不錯的範例,使用itsdangerous 搭配flask

1.啟動後預設port 5000
2.使用curl 建立帳密,因為一開始沒SQL,先用一次這個API後,目錄內會產生sqlite 檔案存放帳號資料
帳號 miguel、密碼 python
$ curl -i -X POST -H "Content-Type: application/json" -d '{"username":"miguel","password":"python"}' http://127.0.0.1:5000/api/users
3.使用curl 取得token
代入帳密,若符合SQL內資料就會回傳JSON 內有Token,時效為600秒
$ curl -u miguel:python -i -X GET http://127.0.0.1:5000/api/token
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 139
Server: Werkzeug/0.9.4 Python/2.7.3
Date: Thu, 28 Nov 2013 20:04:15 GMT
 
{
  "duration": 600,
  "token""eyJhbGciOiJIUzI1NiIsImV4cCI6MTM4NTY2OTY1NSwiaWF0IjoxMzg1NjY5MDU1fQ.eyJpZCI6MX0.XbOEFJkhjHJ5uRINh2JA1BPzXjSohKYDRT472wGOvjc"
}
4.使用curl 呼叫需要身分認證的API
注意因為這個實作是使用HTTP 的authorization 欄位,有帳號跟密碼,帳號填Token,密碼為任意;見下方範例填 ignore
$ curl -u eyJhbGciOiJIUzI1NiIsImV4cCI6MTM4NTY2OTY1NSwiaWF0IjoxMzg1NjY5MDU1fQ.eyJpZCI6MX0.XbOEFJkhjHJ5uRINh2JA1BPzXjSohKYDRT472wGOvjc:ignore -i -X GET http://127.0.0.1:5000/api/resource
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 30
Server: Werkzeug/0.9.4 Python/2.7.3
Date: Thu, 28 Nov 2013 20:05:08 GMT
 
{
  "data""Hello, miguel!"
}

簡單實驗Token 的好處:
1.將範例的api.py 複製一份,然後修改port 4000,再啟動
2.現在兩支程式都啟動後,假設你在port 5000 取得Token,該Token 一樣可以用在port 4000 的API
因為同個目錄有分享同一個SQL
3.簡單得證,若A和B 有分享帳號資料,在A 地方取得Token ,可以在B地方使用Token

沒有留言:

張貼留言

NoSQL Redis intro

Redis是一個使用ANSI C編寫的開源、支援網路、基於記憶體、可選永續性的鍵值對儲存資料庫。 支援rdb 及aof 兩種儲存方式 From  https://zh.wikipedia.org/wiki/Redis Redis 目前擁有兩種資料...