Keath Milligan

On software development, quality, security and broken racecars

JWT authentication with Flask and Angular 2: a simple end-to-end example

flask-angular2-jwt

JSON Web Tokens are a standard method of securing exchanges between two parties (such as web server app and client) that has a number of advantages over other methods of securing exchanges such as cookie-based sessions – enhanced security, less overhead and statelessness to name a few.

In this post, well take a look at using JWT with Flask and Angular 2 and build a simple end-to-end example.

Download or clone the complete source code for this example from github.

The Server

First, let’s start with the server. To provide JWT functionality, I’m using Flask-JWT. This extension enhances Flask by providing a @jwt_required decorator we can attach to any routes we want to protect. The example server code below is pretty similar to the quick start example shown in the Flask-JWT documentation.

flask-jwt/app.py:

Let’s break down the app a bit:

The first thing we do is define a simple user model to represent an “identity”:

In a real world example, you would probably be connecting to a database, directory or some other external service for a user, but for the sake of this simple example, we’ll just hard code a single user.

Next, we declare a couple of functions that Flask-JWT will use to work with our user object:

The authenticate function is called by Flask-JWT when the login API is invoked with a username and password. This function authenticates the user and returns a user object if successful (or None if not).

The identity function is called by Flask-JWT to look up a user by id. In this case, we simply return the one user.

Refer to the official docs for more information on the Flask-JWT API.

Create and configure the Flask app and create the jwt object:

The SECRET_KEY configuration item is used to digitally-sign the tokens, so in a real-world scenario, set this to some appropriately difficult to guess value (e.g., a random string of characters) and ensure that it is not possible for users to access it. See How to generate good secret keys in the Flask Sessions documentation.

Send CORS Headers

Since the debug instance of the Flask server will be running at “http://localhost:5000” and the Angular 2 front-end will be served at “http://localhost:3000”, we need to have the server send some additional headers to enable Cross-Origin Resource Sharing (CORS). Without these headers, the browser will refuse to load any data from the Flask server because it is running at a different URL due to the same-origin policy.

We could use Flask’s ability to serve static assets to serve the Angular 2 app and avoid having to add the CORS headers, but if we did that, we’d lose automatic rebuild on file changes and other benefits we gain from using node development server.

Finally, let’s declare some resources:

The first resource is unprotected and can be accessed without a token. The second requires a valid token and return a 403 without it.

The Front-End

Now let’s have a look at at the front-end code. Angular 2 apps require several configuration files, I’m not going to go through each of these as they are well covered elsewhere. All files necessary to run the example are available in the github repo.

In this example, I’m going to use the angular2-jwt library from auth0. While it isn’t absolutely necessary to use a library for JWT support in your Angular app — you could simply treat the token as opaque and generate the headers yourself — the angular2-jwt library provides some nice functionality, including the ability to decode tokens, check their expiration dates, etc. Note that angular2-jwt will work with any JWT backend, an auth0 account is not required.

app.module.ts:

The main thing we are doing here besides including the augular2-jwt providers is configuring its prefix to “JWT”, which is what Flask-JWT uses as a default.

app.component.ts:

This is a very simple component that displays a message log. The first thing it does is make a regular unauthenticated request to the unprotected resource. This is just to insure the basics are working:

If this request is successful, we proceed with trying to login:

If the login is successful, we save the token in local storage and then use some of the utilities that angular-jwt provides to show some information about the token we just received.

Finally, we request the protected resource using angular-jwt’s AuthHttp provider:

AuthHttp works just like Angular’s standard Http provider, but will automatically include the “Authorization:” header with the token we previously saved.

If everything works as expected, you should see something like this in your browser:

1 Comment

  1. It is not working with Angular 2 AOT Compiler

    in your app.module.ts you have to inject Http, RequestOptions from @angular/http

    and use the following functions

    export function authFactory(http: Http, options: RequestOptions) {
    return new AuthHttp(new AuthConfig({
    // Config options if you want
    }), http, options);
    };

    // Include this in your ngModule providers
    export const authProvider = {
    provide: AuthHttp,
    deps: [Http, RequestOptions],
    useFactory: authFactory
    };

    then you simply include authProvider to your providers.

Leave a Reply

Your email address will not be published.

*

© 2017 Keath Milligan

Theme by Anders NorenUp ↑