I am trying to implement JWT token authentication for my Flask Rest project.
When I authenticate using username and password I get generated token:
http --auth test:testpass POST http://localhost:5000/api/v1/account/token
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Connection: close
Content-Length: 64
Content-Type: application/json
Date: Tue, 29 Nov 2022 09:49:23 GMT
Server: Werkzeug/2.2.2 Python/3.10.7
{
"token": "eyJpZCI6M30.Y4XVow.KH_xDVs5eZ8cM2t8-GGPWZ52mBY"
}
Once I am trying to access the protected page using the token it throws authentication error
http GET http://localhost:5000/api/v1/account/secret "Authorization:Bearer eyJpZCI6M30.Y4XVow.KH_xDVs5eZ8cM2t8-GGPWZ52mBY"
HTTP/1.1 401 UNAUTHORIZED
Access-Control-Allow-Origin: *
Connection: close
Content-Length: 66
Content-Type: application/json
Date: Tue, 29 Nov 2022 09:50:31 GMT
Server: Werkzeug/2.2.2 Python/3.10.7
WWW-Authenticate: Basic realm="Authentication Required"
{
"error": "unauthorized",
"message": "Invalid credentials"
}
Route code to generate token:
@api.route('/account/token', methods=['POST'])
@auth.login_required
def get_auth_token():
if g.current_user.is_anonymous or g.token_used:
return unauthorized('Invalid credentials')
return jsonify({'token': g.current_user.generate_auth_token()})
that calls the function to generate token and verify it once needed:
def generate_auth_token(self):
s = Serializer(current_app.config['SECRET_KEY'])
return s.dumps({'id': self.id})
@staticmethod
def verify_auth_token(token, expiration=3600):
s = Serializer(current_app.config['SECRET_KEY'])
try:
data = s.loads(token, max_age=expiration)
except SignatureExpired:
return abort(400)
except BadSignature:
return abort(400)
return Account.query.get(data['id'])
function that verifyes token or password:
@auth.verify_password
def verify_password(username_or_token, password):
if username_or_token == '':
return False
if password == '':
g.current_user = Account.verify_auth_token(username_or_token)
g.token_used = True
return g.current_user is not None
user = Account.query.filter_by(username=username_or_token).first()
if not user:
return False
g.current_user = user
g.token_used = False
return user.verify_password(password)
Please, advice what am I doing wrong and how to fix it.