I'm working my way through Miguel Grinberg's book Flask Web Development, and I've run into a snag in Chapter 14 (Application Programming Interfaces) with the authentication routine. I'm attempting to update the code to use the current version of flask-HTTPAuth according to the example code in the github repo. I can authenticate to HTTPBasicAuth with email/password, but when I try to pass a token I still get a password prompt.
Here is my app/api/authentication.py file:
from flask import g, jsonify
from flask_httpauth import HTTPBasicAuth, HTTPTokenAuth, MultiAuth
from ..models import User
from . import api
from .errors import forbidden, unauthorized
basic_auth = HTTPBasicAuth()
token_auth = HTTPTokenAuth(scheme='Bearer')
multi_auth = MultiAuth(basic_auth, token_auth)
@basic_auth.verify_password
def verify_password(email, password):
if email == '':
return False
user = User.query.filter_by(email=email).first()
if not user:
return False
g.current_user = user
g.token_used = False
if user.verify_password(password):
return user
else:
return False
@token_auth.verify_token
def verify_token(token):
user = User.verify_auth_token(token)
if user:
g.current_user = user
g.token_used = True
return user
else:
return False
@basic_auth.error_handler
def auth_error():
return unauthorized('Invalid credentials')
@token_auth.error_handler
def auth_error():
return unauthorized('Invalid credentials')
@api.before_request
@multi_auth.login_required
def before_request():
if not g.current_user.is_anonymous and not g.current_user.confirmed:
return forbidden('Unconfirmed account')
@api.route('/tokens/', methods=['POST'])
@multi_auth.login_required
def get_token():
if g.current_user.is_anonymous or g.token_used:
return unauthorized('Invalid credentials')
return jsonify({'token': g.current_user.generate_auth_token(), 'expiration': 3600})
I'm using Python 3.10.6, Flask 2.2.2 and HTTPie 3.2.1. What am I doing wrong?
CodePudding user response:
I've figured it out. The current version of HTTPie (3.2.1) needs to know whether you're sending a token or a userid:password pair. To do this, you use the command
http --auth <username>:<password> ...
for basic authentication or
http --auth-type bearer --auth <token> ...
for token authentication.