1

security.py


    from user import User    
    from werkzeug.security import safe_str_cmp

    users =[User(1,'abc','abc')  ]

    username_mapping = {u.username:u for u in users}

    userid_mapping = {u.uid: u for u in users}

    def authenticate(username,password):
        user= username_mapping.get(username,None)
        if user and safe_str_cmp(user.password , password):
            return users

    def identity(payload):
        user_id=payload['identity']
        return userid_mapping.get(user_id,None)


app.py


    from flask import Flask,request  
    from flask_restful import Api,Resource 
    from flask_jwt import JWT, jwt_required  
    from security import authenticate,identity


    app = Flask(__name__)  
    app.security_key='cool'  
    api = Api(app)


    jwt = JWT(app,authenticate,identity) #create new endpoint /auth


/auth POST method of above JWT function shows 500 Internal server error and gives below error log

Traceback (most recent call last):
  File "/usr/lib/python3.7/site-packages/flask/app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/lib/python3.7/site-packages/flask/app.py", line 1815, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/lib/python3.7/site-packages/flask_restful/__init__.py", line 273, in error_router
    return original_handler(e)
  File "/usr/lib/python3.7/site-packages/flask/app.py", line 1718, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/lib/python3.7/site-packages/flask/_compat.py", line 35, in reraise
    raise value
  File "/usr/lib/python3.7/site-packages/flask/app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/lib/python3.7/site-packages/flask/app.py", line 1799, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/iamabhi67/.local/lib/python3.7/site-packages/flask_jwt/__init__.py", line 125, in _default_auth_request_handler
    access_token = _jwt.jwt_encode_callback(identity)
  File "/home/iamabhi67/.local/lib/python3.7/site-packages/flask_jwt/__init__.py", line 62, in _default_jwt_encode_handler
    payload = _jwt.jwt_payload_callback(identity)
  File "/home/iamabhi67/.local/lib/python3.7/site-packages/flask_jwt/__init__.py", line 53, in _default_jwt_payload_handler
    identity = getattr(identity, 'id') or identity['id']
AttributeError: 'list' object has no attribute 'id'
Abhishek Parmar
  • 287
  • 2
  • 8
  • 21
  • To answer your questions, it sounds like your user is a list instead of an object/dictionary/whatever. Unrelated, you might want to check out Flask-JWT-Extended instead. Flask-JWT has been abandoned for years now. You also write your own login endpoint in Flask-JWT-Extended so you don't have to deal with the limits of the `authenticate` method in Flask-JWT. – vimalloc Mar 18 '19 at 20:23

3 Answers3

1

the return should be user, not users

  def authenticate(username,password):
    user= username_mapping.get(username,None)
    if user and safe_str_cmp(user.password , password):
        return user
0

Your authenticate function returns users which is a list. It should return a user object (which has an id attribute). Check out the Quickstart.

Tomáš Linhart
  • 9,832
  • 1
  • 27
  • 39
0
userid_mapping = {u.uid: u for u in users}

you are setting id as uid in your dict. comprehension, your code works with {u.id: u for u in users} (on my machine at least). JWT is looking for id attribute upon not finding it throws that nasty exception.

Shek
  • 1,543
  • 6
  • 16
  • 34