Flask JWT Extended 的令牌和刷新令牌


更多擴展

https://www.jianshu.com/p/10d0da01244c

**概念理解:**
* 刷新令牌的過期時間設置的要比 token久 
* 我們使用token來進行用戶是否登錄判斷, 當token過期后, 前端使用 刷新令牌, 來獲取新的token

**實現步驟**
* 當用戶登錄成功后,返回 token 和 refresh_token
* 前端將其保存起來(保存位置看情況而定)
* 在發送請求的時候攜帶上 token, 默認的是在 headers 的 Authorization, 可以自己設置(看下邊鏈接)這里我設置在json中獲取
* 后台判斷是否符合要求,是否過期, 一般由自帶裝飾器完成
* 假如過期,前端,攜帶 refresh_token 默認的是在 Authorization, 可以自己設置(看下邊鏈接) 去后台獲取新的token,然后保存,再次請求
后端實現:

from flask import Flask, request, jsonify, render_template
from flask_jwt_extended import (
    JWTManager, jwt_required, create_access_token,
    jwt_refresh_token_required, create_refresh_token,
    get_jwt_identity
)
import config
app = Flask(__name__)
app.config["JWT_ACCESS_TOKEN_EXPIRES"] = 5
app.config['JWT_SECRET_KEY'] = 'super-secret'  # Change this!
app.config["JWT_TOKEN_LOCATION"] = ['json']  # 設置從前端請求的json數據 中獲取 token 默認是在Authorization 
app.confg["JWT_JSON_KEY"] = "token" # 設置 從json中的 token字段獲取,token, # app.config["JWT_REFRESH_JSON_KEY"] = "token" app.config.from_object(config) jwt = JWTManager(app) @app.route("/index", methods=["GET"]) def index(): return render_template("login.html") @app.route('/login', methods=['POST']) def login(): # if request.method == "GET": # return render_template("login.html") # else: username = request.form.get('username', None) password = request.form.get('password', None) if username != 'test' or password != 'test': return jsonify({"msg": "Bad username or password"}), 401 # Use create_access_token() and create_refresh_token() to create our # access and refresh tokens ret = { 'access_token': create_access_token(identity={"username": "liuyong", "age": "24"}), 'refresh_token': create_refresh_token(identity={"username": "liuyong", "age": "25"}) } return jsonify(ret), 200 # The jwt_refresh_token_required decorator insures a valid refresh # token is present in the request before calling this endpoint. We # can use the get_jwt_identity() function to get the identity of # the refresh token, and use the create_access_token() function again @app.route("/test", methods=["POST"]) @jwt_required def test(): a = get_jwt_identity() print(a.get("username")) print(a) return jsonify({"tets": "test"}) # to make a new access token for this identity. @app.route('/refresh', methods=['POST']) @jwt_refresh_token_required def refresh(): current_user = get_jwt_identity() ret = { 'access_token': create_access_token(identity=current_user) } return jsonify(ret), 200 @app.route('/protected', methods=['GET']) @jwt_required def protected(): username = get_jwt_identity() return jsonify(logged_in_as=username), 200 if __name__ == '__main__': app.run()

  

前端代碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>登錄</title>
    <!-- <link rel="stylesheet" href="js/jquery-3.5.1.min.js"> -->
    <link rel="stylesheet" href="static/bootstrap/css/bootstrap.min.css">
    <link rel="stylesheet" href="static/css/style.css">
</head>
<body>
    <div class="row">

            <div class="login-div col-xs-12 col-sm-2 col-sm-offset-5">
                <div class="form-group first">
                    <label for="exampleInputEmail1">用戶名</label>
                    <input type="username" name="username" class="form-control username" id="exampleInputuserName1" placeholder="用戶名">
                </div>
                <div class="form-group">
                    <label for="exampleInputPassword1">密碼</label>
                    <input type="password" name="password" class="form-control password" id="exampleInputPassword1" placeholder="Password">
                </div>

                <div class="login-btn">
                    <button type="button" class="btn btn-info">登錄</button>
                </div>
                <hr/>
                <div class="footer" >
                    <p> 還沒有賬戶~ <a class="register">注冊</a> </p>
                </div>
            </div>
    </div>
    <script src="static/js/jquery-3.5.1.min.js"></script>
    <script>
        $(".btn").click(function(){
            var username = $(".username").val();
            var password = $(".password").val();
            $.ajax({
                url: "/login",
                type: "POST",
                data: {"username": username, "password": password},
                success: function(data){
                    sessionStorage.setItem("token", data.access_token),
                    sessionStorage.setItem("refree_token", data.refresh_token),
                    console.log(data),
                    console.log(sessionStorage.getItem("token"))
                    console.log(sessionStorage.se)
                    
                    // window.location.href = "/test"
                }
            })
        });
        $(".register").click(function(){ # 這里 攜帶token 向 test 發送post請求
            var data = {"token": sessionStorage.getItem("token")}
            $.ajax({
                        url: "/test",
                        type: "POST",
                        dataType:"json",
                        contentType:"application/json",
                        data: JSON.stringify(data),
                        success: function(data){
                            console.log(data)
                        },
 
                        error: function(zhr){ # 這里未作其他判斷, 只是當失敗的時候(在測試用一般為token過期),使用 refresh_token 從后台獲取新的token
                            var haha ={"token": sessionStorage.getItem("token"), "refresh_token": sessionStorage.getItem("refree_token")};
                                $.ajax({
                                url: "/refresh",
                                type: "post",
                                contentType:"application/json",
                                data: JSON.stringify(haha), # 因為之前設置了從json中獲取,所以務必保證,前端向后台發送的數據為 json數據,否則會獲取不到
                                success: function(data){
                                    sessionStorage.setItem("token", data.access_token) # 重新設置到session中
                                }
                             })
                        }
                })
        });
    </script>
</body>
</html>

  

下邊這兩個仔細看下也就明白了
https://flask-jwt-extended.readthedocs.io/en/latest/refresh_tokens/
https://flask-jwt-extended.readthedocs.io/en/stable/options/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM