Created
February 17, 2021 04:42
-
-
Save bitjockey42/4921deadd3f57ec248796b83495baf54 to your computer and use it in GitHub Desktop.
Breaking changes in flask-jwt-extended requires these changes in auth/views.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from flask import request, jsonify, Blueprint, current_app as app | |
from flask_jwt_extended import ( | |
create_access_token, | |
create_refresh_token, | |
jwt_required, | |
get_jwt_identity, | |
get_jwt, | |
) | |
from myapi.models import User | |
from myapi.extensions import pwd_context, jwt, apispec | |
from myapi.auth.helpers import revoke_token, is_token_revoked, add_token_to_database | |
blueprint = Blueprint("auth", __name__, url_prefix="/auth") | |
@blueprint.route("/login", methods=["POST"]) | |
def login(): | |
"""Authenticate user and return tokens | |
--- | |
post: | |
tags: | |
- auth | |
requestBody: | |
content: | |
application/json: | |
schema: | |
type: object | |
properties: | |
username: | |
type: string | |
example: myuser | |
required: true | |
password: | |
type: string | |
example: P4$$w0rd! | |
required: true | |
responses: | |
200: | |
content: | |
application/json: | |
schema: | |
type: object | |
properties: | |
access_token: | |
type: string | |
example: myaccesstoken | |
refresh_token: | |
type: string | |
example: myrefreshtoken | |
400: | |
description: bad request | |
security: [] | |
""" | |
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 or not password: | |
return jsonify({"msg": "Missing username or password"}), 400 | |
user = User.query.filter_by(username=username).first() | |
if user is None or not pwd_context.verify(password, user.password): | |
return jsonify({"msg": "Bad credentials"}), 400 | |
access_token = create_access_token(identity=user.id) | |
refresh_token = create_refresh_token(identity=user.id) | |
add_token_to_database(access_token, app.config["JWT_IDENTITY_CLAIM"]) | |
add_token_to_database(refresh_token, app.config["JWT_IDENTITY_CLAIM"]) | |
ret = {"access_token": access_token, "refresh_token": refresh_token} | |
return jsonify(ret), 200 | |
@blueprint.route("/refresh", methods=["POST"]) | |
@jwt_required(refresh=True) | |
def refresh(): | |
"""Get an access token from a refresh token | |
--- | |
post: | |
tags: | |
- auth | |
parameters: | |
- in: header | |
name: Authorization | |
required: true | |
description: valid refresh token | |
responses: | |
200: | |
content: | |
application/json: | |
schema: | |
type: object | |
properties: | |
access_token: | |
type: string | |
example: myaccesstoken | |
400: | |
description: bad request | |
401: | |
description: unauthorized | |
""" | |
current_user = get_jwt_identity() | |
access_token = create_access_token(identity=current_user) | |
ret = {"access_token": access_token} | |
add_token_to_database(access_token, app.config["JWT_IDENTITY_CLAIM"]) | |
return jsonify(ret), 200 | |
@blueprint.route("/revoke_access", methods=["DELETE"]) | |
@jwt_required | |
def revoke_access_token(): | |
"""Revoke an access token | |
--- | |
delete: | |
tags: | |
- auth | |
responses: | |
200: | |
content: | |
application/json: | |
schema: | |
type: object | |
properties: | |
message: | |
type: string | |
example: token revoked | |
400: | |
description: bad request | |
401: | |
description: unauthorized | |
""" | |
jti = get_jwt()["jti"] | |
user_identity = get_jwt_identity() | |
revoke_token(jti, user_identity) | |
return jsonify({"message": "token revoked"}), 200 | |
@blueprint.route("/revoke_refresh", methods=["DELETE"]) | |
@jwt_required(refresh=True) | |
def revoke_refresh_token(): | |
"""Revoke a refresh token, used mainly for logout | |
--- | |
delete: | |
tags: | |
- auth | |
responses: | |
200: | |
content: | |
application/json: | |
schema: | |
type: object | |
properties: | |
message: | |
type: string | |
example: token revoked | |
400: | |
description: bad request | |
401: | |
description: unauthorized | |
""" | |
jti = get_jwt()["jti"] | |
user_identity = get_jwt_identity() | |
revoke_token(jti, user_identity) | |
return jsonify({"message": "token revoked"}), 200 | |
@jwt.user_lookup_loader | |
def user_loader_callback(identity): | |
return User.query.get(identity) | |
@jwt.token_in_blocklist_loader | |
def check_if_token_revoked(decoded_token): | |
return is_token_revoked(decoded_token) | |
@blueprint.before_app_first_request | |
def register_views(): | |
apispec.spec.path(view=login, app=app) | |
apispec.spec.path(view=refresh, app=app) | |
apispec.spec.path(view=revoke_access_token, app=app) | |
apispec.spec.path(view=revoke_refresh_token, app=app) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hello :). Is this project open source? If yes can I have the repo link. I want to learn your flask folder structure.