Flask Flask-JWT-拡張を使用してJWTトークンを送信

17736 ワード

Python、Flask JWT

  • PythonはPyJWTを使用してJWTを使用できる.
  • https://pyjwt.readthedocs.io/en/latest/usage.html
  • https://pyjwt.readthedocs.io/en/latest/
  • Flask JWTが使用するライブラリを使用すると、Flask-JWT-拡張を使用するとより便利に使用できます。だから利用します.
  • このライブラリは Flask-JWT-Extended
  • Flask-JWT-Extended

  • 取付pip install flask-jwt-extended
  • タグ値の作成と検索


    https://flask-jwt-extended.readthedocs.io/en/stable/basic_usage/
  • app.configにsecretKeyを登録してjwtトークンを作成します.
  • app = Flask(__name__)
    app.config["JWT_SECRET_KEY"] = "super-secret"
    jwt = JWTManager(app)
  • 識別子を設定しtokenを生成する.create_access_token(identity=username)
  • from flask_jwt_extended import create_access_token
    access_token = create_access_token(identity=username)
    ## return jsonify(access_token=access_token)
  • ログインを想定し、id、パスワードをランダムに指定し、トークンを発行する.
  • from flask import Flask, jsonify
    
    from flask_jwt_extended import JWTManager
    from flask_jwt_extended import create_access_token
    
    app = Flask(__name__)
    
    app.config["JWT_SECRET_KEY"] = "munjibang"
    jwt = JWTManager(app)
    
    @app.route("/users/login", methods=['POST'])
    def home():
        user_id = "id1"
        password = "password1"
        access_token = create_access_token(identity=user_id)
        print(access_token)
        return jsonify({"access_token":access_token})
    
    if __name__ == '__main__':
        app.run('0.0.0.0', port=5000, debug=True)
    
  • 可視結果値
  • ペイロードに識別子に加えて他の情報を追加する必要がある場合、


    https://flask-jwt-extended.readthedocs.io/en/stable/add_custom_data_claims/参照https://github.com/vimalloc/flask-jwt-extended/issues/317
  • クレーム提出
  •         	@app.route("/login", methods=["POST"])
                def login():
                    username = request.json.get("username", None)
                    password = request.json.get("password", None)
                    if username != "test" or password != "test":
                        return jsonify({"msg": "Bad username or password"}), 401
    
                    # You can use the additional_claims argument to either add
                    # custom claims or override default claims in the JWT.
                    additional_claims = {"aud": "some_audience", "foo": "bar"}
                    access_token = create_access_token(username, additional_claims=additional_claims)
                    return jsonify(access_token=access_token)
    

    タグ値から情報を検索


    使用
  • get_jwt_identity()識別子として入力した値を問い合わせることができる

  • 有効なトークンが存在する場合のみアクセスが許可されます


    使用
  • jwt_required()
  • endpointに到達する前に有効なJWTトークンがあるか確認する
  • https://flask-jwt-extended.readthedocs.io/en/stable/api/#flask_jwt_extended.jwt_required
  • https://flask-jwt-extended.readthedocs.io/en/stable/api/#flask_jwt_extended.jwt_required
  • 
    @app.route("/users/protected")
    @jwt_required()
    def protected():
        current_user_id = get_jwt_identity()
        return jsonify(logged_in_as=current_user_id), 200
    
    if __name__ == '__main__':
        app.run('0.0.0.0', port=5000, debug=True)

    参考にする。POST MAN送信トークン値

  • https://learning.postman.com/docs/sending-requests/authorization/#bearer-token
  • 自動ラベルページタイプをBearerTokenに設定し、トークン値を提供する
  • 州の引用符がなく、Token値のみ
  • ステータスコードなし200でも良い
  • @jwt_required(optional=True)


    @jwt required()で値がTrueの場合、有効なトークンの有無に応じてブランチ処理を行うことができます
    @jwt_required(optional=True)
    def place(place_id):
        current_identity = get_jwt_identity()
        if not current_identity:
            return jsonify({'result':'fail'})
    
        places = to_place_detail_dto(
            list(db.places.find({'_id': ObjectId(place_id)})))
        return jsonify({'places': places})

    タグの有効期限が切れた場合の個別処理


    要求されたトークンが期限切れになった場合、自動的にメッセージ{"msg":"Tokenが期限切れ"}が送信されます.サーバ側が管理しているので、他の処理を制御する必要があります.
  • docs https://flask-jwt-extended.readthedocs.io/en/stable/changing_default_behavior/
  • https://stackoverflow.com/questions/68955402/flask-flask-jwt-extended-trying-to-custom-handle-unauthorized-error
  • このように行う.私はもともとabortでエラーを生成しましたが、そうするとerrorhandlerはそれを捕まえられません.
  • このように処理方法を分離する.
  • なるほどこの方法で処理
  • サーバ側でレンダリングするには、問題タグをセッションに追加する必要があります。

  • 追加方法
    https://flask-jwt-extended.readthedocs.io/en/3.0.0_release/tokens_in_cookies/
  • この操作で良い、注意事項は
  • app = Flask(__name__)
    
    # Configure application to store JWTs in cookies. Whenever you make
    # a request to a protected endpoint, you will need to send in the
    # access or refresh JWT via a cookie.
    app.config['JWT_TOKEN_LOCATION'] = ['cookies']
    
    # Set the cookie paths, so that you are only sending your access token
    # cookie to the access endpoints, and only sending your refresh token
    # to the refresh endpoint. Technically this is optional, but it is in
    # your best interest to not send additional cookies in the request if
    # they aren't needed.
    app.config['JWT_ACCESS_COOKIE_PATH'] = '/api/'
    app.config['JWT_REFRESH_COOKIE_PATH'] = '/token/refresh'
    
    # Disable CSRF protection for this example. In almost every case,
    # this is a bad idea. See examples/csrf_protection_with_cookies.py
    # for how safely store JWTs in cookies
    app.config['JWT_COOKIE_CSRF_PROTECT'] = False
    
  • この設定部分を追加する必要がある
  • これで完成
  • logout


    https://flask-jwt-extended.readthedocs.io/en/stable/refreshing_tokens/
  • これによる
  • @app.route('/signout', methods=['POST'])
    def signout():
        response = make_response(redirect(url_for("places_all")))
        unset_jwt_cookies(response)
        return response

    追加

  • 複雑なオブジェクトを追加するために使用可能 user_identity_loader(),
  • https://flask-jwt-extended.readthedocs.io/en/stable/api/#flask_jwt_extended.JWTManager.user_identity_loader
  • https://fenderist.tistory.com/144