用講故事的方法講述 JWT
JWT 就像一張門禁卡
小明管理著一個(gè)小區(qū)的物業(yè),負(fù)責(zé)整個(gè)小區(qū)的出入安全。剛開始的時(shí)候小明決定要保險(xiǎn)一點(diǎn),所有出入小區(qū)的都要驗(yàn)證業(yè)主的本人信息块请。
所以他搞了個(gè)規(guī)定,每個(gè)進(jìn)小區(qū)的人都要驗(yàn)證身份證和指紋拳缠,通過后臺(tái)證明你是業(yè)主才讓你進(jìn)去墩新。剛開始的時(shí)候這個(gè)規(guī)定還行,但是隨著小區(qū)的出入人員變多窟坐,處理速度太慢海渊,小區(qū)業(yè)主經(jīng)常需要排隊(duì)進(jìn)入小區(qū)。
收到了大量的投訴電話只后小明決定反思一下哲鸳,決定使用門禁卡來解決這個(gè)效率問題臣疑。他于是讓業(yè)主去物業(yè)做一個(gè)一次性的身份驗(yàn)證,通過了之后就發(fā)一張門禁卡給業(yè)主徙菠,不過門禁卡有期限限制讯沈,半年之后就需要更新一下,而且業(yè)主刷卡的時(shí)候懒豹,物業(yè)只需要驗(yàn)證下這是不是我們發(fā)的業(yè)主卡就行了芙盘。
物業(yè)在處理門禁卡信息的時(shí)候,會(huì)從門禁卡里面解密信息脸秽,那個(gè)信息里面帶有業(yè)主自己本人的信息儒老。
在這個(gè)故事里面,
- 第一個(gè)的每次進(jìn)入小區(qū)都需要驗(yàn)證就是傳統(tǒng)的session登錄方法
- 門禁卡制度就是jwt
用python實(shí)踐 JWT
使用JWT實(shí)踐的方法很簡單记餐,就是分三部分驮樊。
- 服務(wù)器驗(yàn)證是否是用戶
- 服務(wù)器為用戶生成一個(gè)TOKEN
- 用戶訪問服務(wù)器的時(shí)候帶著那個(gè)TOKEN
- 服務(wù)驗(yàn)證TOKEN是否合法
- 用戶訪問內(nèi)容
完整的例子
from flask import Flask, jsonify, request
from flask_jwt_extended import (
JWTManager, jwt_required, create_access_token,
get_jwt_identity
)
app = Flask(__name__)
# Setup the Flask-JWT-Extended extension
app.config['JWT_SECRET_KEY'] = 'super-secret' # Change this!
jwt = JWTManager(app)
# Provide a method to create access tokens. The create_access_token()
# function is used to actually generate the token, and you can return
# it to the caller however you choose.
@app.route('/login', methods=['POST'])
def login():
if not request.is_json:
return jsonify({"msg": "Missing JSON in request"}), 400
username = request.json.get('username', None)
password = request.json.get('password', None)
if not username:
return jsonify({"msg": "Missing username parameter"}), 400
if not password:
return jsonify({"msg": "Missing password parameter"}), 400
if username != 'test' or password != 'test':
return jsonify({"msg": "Bad username or password"}), 401
# Identity can be any data that is json serializable
# 服務(wù)器為用戶生成一個(gè)TOKEN
access_token = create_access_token(identity=username)
return jsonify(access_token=access_token), 200
# Protect a view with jwt_required, which requires a valid access token
# in the request to access.
@app.route('/protected', methods=['GET'])
@jwt_required
def protected():
# Access the identity of the current user with get_jwt_identity
# 服務(wù)驗(yàn)證TOKEN是否合法
current_user = get_jwt_identity()
# 用戶訪問內(nèi)容
return jsonify(logged_in_as=current_user), 200
if __name__ == '__main__':
app.run()
運(yùn)行該程序
- 用戶如何獲得token
curl -H "Content-Type: application/json" -X POST \
-d '{"username":"test","password":"test"}' http://localhost:5000/login
代碼會(huì)返回類似于
{"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmcmVzaCI6dHJ1ZSwianRpIjoiZjhmNDlmMjUtNTQ4OS00NmRjLTkyOWUtZTU2Y2QxOGZhNzRlIiwidXNlcl9jbGFpbXMiOnt9LCJuYmYiOjE0NzQ0NzQ3OTEsImlhdCI6MTQ3NDQ3NDc5MSwiaWRlbnRpdHkiOiJ0ZXN0IiwiZXhwIjoxNDc0NDc1NjkxLCJ0eXBlIjoiYWNjZXNzIn0.vCy0Sec61i9prcGIRRCbG8e9NV6_wFH2ICFgUGCLKpc"}
- 用戶訪問的過程中帶上token
export ACCESS="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmcmVzaCI6dHJ1ZSwianRpIjoiZjhmNDlmMjUtNTQ4OS00NmRjLTkyOWUtZTU2Y2QxOGZhNzRlIiwidXNlcl9jbGFpbXMiOnt9LCJuYmYiOjE0NzQ0NzQ3OTEsImlhdCI6MTQ3NDQ3NDc5MSwiaWRlbnRpdHkiOiJ0ZXN0IiwiZXhwIjoxNDc0NDc1NjkxLCJ0eXBlIjoiYWNjZXNzIn0.vCy0Sec61i9prcGIRRCbG8e9NV6_wFH2ICFgUGCLKpc"
然后訪問接口
curl -H "Authorization: Bearer $ACCESS" http://localhost:5000/protected
最后返回
{
"logged_in_as": "test"
}