We will configure the Flask-HTTPAuth
extension to work with our User
model to verify passwords and set the authenticated user associated with a request. We will declare a custom function that this extension will use as a callback to verify a password. We will create a new base class for our resources that will require authentication. Open the api/views.py
file and add the following code after the last line that uses the import
statement and before the lines that declares the Blueprint
instance . The code file for the sample is included in the restful_python_chapter_07_02
folder:
from flask_httpauth import HTTPBasicAuth from flask import g from models import User, UserSchema auth = HTTPBasicAuth() @auth.verify_password def verify_user_password(name, password): user = User.query.filter_by(name=name).first() if not user or not user.verify_password(password): return False g.user = user return True class AuthRequiredResource(Resource): method_decorators = [auth.login_required]
First, we create an instance of the flask_httpauth.HTTPBasicAuth
class named auth
. Then, we declare the verify_user_password
function that receives a name and a password as arguments. The function uses the @auth.verify_password
decorator to make this function become the callback that Flask-HTTPAuth
will use to verify the password for a specific user. The function retrieves the user whose name matches the name
specified in the argument and saves its reference in the user
variable. If a user is found, the code checks the results of the user.verify_password
method with the received password as an argument.
If either a user isn't found or the call to user.verify_password
returns False
, the function returns False
and the authentication will fail. If the call to user.verify_password
returns True
, the function stores the authenticated User
instance in the user attribute for the flask.g
object.
The flask.g
object is a proxy that allows us to store on this whatever we want to share for one request only. The user
attribute we added to the flask.g
object will be only valid for the active request and it will return different values for each different request. This way, it is possible to use flask.g.user
in another function or method called during a request to access details about the authenticated user for the request.
Finally, we declared the AuthRequiredResource
class as a subclass of flask_restful.Resource
. We just specified auth.login_required
as one of the members of the list that we assign to the method_decorators
property inherited from the base class. This way, all the methods declared in a resource that uses the new AuthRequiredResource
class as its superclass will have the auth.login_required
decorator applied to them, and therefore, any method that is called to the resource will require authentication.
Now, we will replace the base class for the existing resource classes to make them inherit from AuthRequiredResource
instead of Resource
. We want any of the requests that retrieve or modify categories and messages to be authenticated.
The following lines show the declarations for the four resource classes:
class MessageResource(Resource): class MessageListResource(Resource): class CategoryResource(Resource): class CategoryListResource(Resource):
Open the api/views.py
file and replace Resource
by AuthRequiredResource
in the previously shown four lines that declare the resource classes. The following lines show the new code for each resource class declaration:
class MessageResource(AuthRequiredResource): class MessageListResource(AuthRequiredResource): class CategoryResource(AuthRequiredResource): class CategoryListResource(AuthRequiredResource):
3.140.197.10