2

I've used PyJWT for authenticating the user now my main concern is how to use authentication decorator in API endpoints as I've addes SQL query to to fetch user detail using uid in my route but in token_required definition for current user do I've to add that query again?

Ex. After login I want to access API to display user profile.

@app.route('/users/<uid>', methods=['GET'])
**@token_required** ??

I've used SqlAlchemy core to execute and get data from database in my route.

In token_required definition can we add SqlAlchmey core query for current user & how to implement because I've already used that in my route /users/.

def token_required(f):
   @wraps(f)
   def decorator(*args, **kwargs):

      token = None

      if 'x-access-tokens' in request.headers:
         token = request.headers['x-access-tokens']

      if not token:
         return jsonify({'message': 'a valid token is missing'})

      try:
         data = jwt.decode(token, app.config['SECRET_KEY'])
         current_user = User.query.filter_by(uid=data['uid']).first()
      except:
         return jsonify({'message': 'token is invalid'})

      return f(current_user, *args, **kwargs)
   return decorator
@app.route('/users/<uid>', methods=['GET'])
def profile_view(uid):
    print("user_details")
    conn = engine.connect()
    str_sql = text(**"""SELECT * FROM user WHERE uid = uid""",{"uid": uid}**)
    results = conn.execute(str_sql).fetchall()
    print(results)
    return users_scehma.dump(results)

Naveen Pandia
  • 107
  • 13
R P
  • 41
  • 5

1 Answers1

0

First of all import flask and JWTManager

from flask import Flask, jsonify
from flask_jwt_extended import (create_access_token,get_jwt_identity,jwt_required,JWTManager)

Define the Flask app and set a JWT_SECRET_KEY

app = Flask(__name__)
app.config["JWT_SECRET_KEY"] = "supersecret"  # Change this!

Initialize the jwt with the app

jwt = JWTManager(app)

Make a @app.route to define the method and path. def login() is to get the Authentifikation key

@app.route("/token/login", methods=["GET"])
def login():
    additional_claims = {"aud": "some_audience", "foo": "bar"}
    access_token = create_access_token(identity="username", additional_claims=additional_claims) #you can add additional parameters
    return jsonify(access_token=access_token),200#, encoded=False), 200

Our second route is protected to with @jwt_required()

@app.route("/protected", methods=["GET"])
@jwt_required()
def protected():
    # Access the identity of the current user with get_jwt_identity
    current_user = get_jwt_identity()
    return jsonify(logged_in_as=current_user), 200
if __name__ == '__main__':
    app.run()

the code looks like this at the end:

from flask import Flask, jsonify
from flask_jwt_extended import (create_access_token,get_jwt_identity,jwt_required,JWTManager)

app = Flask(__name__)
app.config["JWT_SECRET_KEY"] = "supersecret"  # Change this!

jwt = JWTManager(app)

@app.route("/token/login", methods=["Get"])
def login():
    additional_claims = {"aud": "some_audience", "foo": "bar"}
    access_token = create_access_token(identity="username", additional_claims=additional_claims) #you can add additional parameters
    return jsonify(access_token=access_token),200#, encoded=False), 200

@app.route("/protected", methods=["GET"])
@jwt_required()
def protected():
    # Access the identity of the current user with get_jwt_identity
    current_user = get_jwt_identity()
    return jsonify(logged_in_as=current_user), 200

if __name__ == '__main__':
    app.run()

Output:

{"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmcmVzaCI6ZmFsc2UsImlhdCI6MTY2Njk2MTA3MCwianRpIjoiNGViY2MwYzAtMjAxYy00ODAwLThjMTUtNmQzNDQ1MmVhYmQxIiwidHlwZSI6ImFjY2VzcyIsInN1YiI6InVzZXJuYW1lIiwibmJmIjoxNjY2OTYxMDcwLCJleHAiOjE2NjY5NjE5NzAsImF1ZCI6InNvbWVfYXVkaWVuY2UiLCJmb28iOiJiYXIifQ.qAn8rhsxyF_00Ayu9L7ddd6USkbYIHKvsUneDMzzjHs"}

To use the access_token we need an module that can call the Webserver with header. I will use requests

import requests
key = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmcmVzaCI6ZmFsc2UsImlhdCI6MTY2Njk2MTA3MCwianRpIjoiNGViY2MwYzAtMjAxYy00ODAwLThjMTUtNmQzNDQ1MmVhYmQxIiwidHlwZSI6ImFjY2VzcyIsInN1YiI6InVzZXJuYW1lIiwibmJmIjoxNjY2OTYxMDcwLCJleHAiOjE2NjY5NjE5NzAsImF1ZCI6InNvbWVfYXVkaWVuY2UiLCJmb28iOiJiYXIifQ.qAn8rhsxyF_00Ayu9L7ddd6USkbYIHKvsUneDMzzjHs"
requests.get("http://127.0.0.1:5000/protected", headers={'Authorization': 'Bearer ' + key}

If you want to set an expire time set this:

app.config["JWT_SECRET_KEY"] = "supersecret"  # Change this!

from datetime import timedelta
pp.config["JWT_ACCESS_TOKEN_EXPIRES"] = timedelta(minutes=1000)
jwt = JWTManager(app)

if you need to know more you can follow the link: https://flask-jwt-extended.readthedocs.io/en/stable/token_locations/

On the right side is an Navigation to go throw the sides. This will also show you how to use Cookies with the @jwt_required()

hase1010
  • 57
  • 4
  • Though what you've scripted is right but in my code I've used PyJWT because now jwt-extended is not updating its method anymore plus for SQLAlchemy_core Pyjwt works better. – R P Oct 28 '22 at 13:10