title: Firebase Auth on your App Engine Python Application description: Learn how to authenticate API requests using Firebase Auth on App Engine. author: archelogos tags: App Engine, Python, Falcon, API, Firebase, Auth, JWT date_published: 2017-05-05
In this tutorial you will learn how to authenticate the requests that hit your API with JSON Web Tokens (JWT) using Firebase Auth.
Firebase is a platform that provides you tools and infrastructure to build your apps easily.
To understand properly what a JWT is, you can find more information about it here: JWT.
This guide takes the basic concepts of an API from this tutorial: Previous Tutorial.
- Create a Python app that uses Falcon as a framework.
- Run the app locally.
- Use Firebase Auth to authenticate and validate the requests.
- Deploy the Python app to Google App Engine standard environment.
This tutorial does not use billable components of Google Cloud Platform so you do not need to enable the billing for your project to complete this tutorial.
Before you begin
- Create a project in the Google Cloud Platform Console and make note of the project ID.
- Install the Google Cloud SDK.
- Import the Google Cloud Project in the Firebase Console.
- Go to the Authentication section in the Firebase Console and enable at least one Sign-in provider. Follow this link in case you need some information about how to do it, see: https://firebase.google.com/docs/auth/.
Preparing the app
Follow the steps described in the previous tutorial. Once the app is running locally, move on to the next steps.
Add the following line to the
app.yamlfile adding the following contents:
env_variables: GCLOUD_PROJECT: '[YOUR_PROJECT_ID]'
firebase-adminlibrary to the
__init__.pyfile and intialize the Firebase app.
import firebase_admin ... default_app = firebase_admin.initialize_app()
Modify now the
AuthMiddlewareusing the Firebase ID Token Validator.
... from firebase_admin import auth class AuthMiddleware(object): """.""" def process_request(self, req, resp): auth_value = req.get_header('Authorization', None) if auth_value is None or len(auth_value.split(' ')) != 2 or not self.token_is_valid(req, auth_value.split(' ')): raise falcon.HTTPUnauthorized(description='Unauthorized') def token_is_valid(self, req, token): try: decoded_token = auth.verify_id_token(token) req.context['auth_user'] = decoded_token except Exception as e: return False if not decoded_token: return False return True
Because this middleware applies to all endpoints, from now you will need to send your requests with an 'Authorization' header which contains a valid JWT Token.
Header['Authorization'] = 'Bearer [JWT_TOKEN]'
You could also verify the user role in a separated Falcon hook to determine if the user has enough permission to do the operation.
def is_admin(req, resp, resource, params): # Good place to check the user role. logging.info(req.context['auth_user']) ... @falcon.before(api_key) @falcon.before(is_admin) @falcon.after(say_bye_after_operation) def on_post(self, req, resp): ...
As you can see, we are using the
req.contextto pass variables from the middleware layer to the hooks.
To generate ID Tokens and because of Firebase does not provide an API to generate them, we have to simulate a client sign in.
To do that you can use several Firebase client libraries like AngularFire or FirebaseUI. You can find a sample in this repo jwt. Be sure that you set your Firebase Credentials before generate a token.
Running the app
Install the dependencies into the
libfolder with pip.
pip install -t lib -r requirements.txt
Execute the following command to run the app.
Visit http://localhost:8080 to see the app running.
Run the JWT generator using (for instance) a NodeJS http server.
Be sure that you have already installed Node.js in your local machine and install a http-server module globally.
node -v npm -g install http-server cd jwt http-server . -p 9000
Visit http://localhost:9000 in the browser, sign in and copy the JWT.
Run the following command to test one of the endpoints:
curl -X GET \ http://localhost:8080/ \ -H 'authorization: Bearer [JWT_TOKEN]' \ -H 'cache-control: no-cache'
Deploying the app
Run the following command to deploy your app:
gcloud app deploy
http://[YOUR_PROJECT_ID].appspot.comto see the deployed app.
[YOUR_PROJECT_ID]with your Google Cloud Platform project ID.
Run the following command to view your app:
gcloud app browse