Tutorial: Setting Up the OAuth2 Server

Setting Up the OAuth2 Server

Besides providing compatibility with OAuth2 login sources, Flitter Auth ships with the ability to use your application as an OAuth2 server as well. This would allow other applications to implement "Sign in with X" buttons that redirect users to your application, have them sign in, then redirect back.

Again, by default the only supported grant type is authorization_code.

Conceptual

OAuth2 authentication is a fundamentally different way of authenticating a user (as compared to the local database-driven auth, and the LDAP auth). Rather than providing a username and password to a login form on your application, the application redirects the user to the login page for a different provider.

Once the user has signed in with your application, your application redirects the user back to a specific endpoint on the client application with a special token known as an authorization code. That application then takes this authorization code and (by making a web request from the server itself) redeems this authorization code for a bearer token, which can be used to access some API endpoint on your application.

Using that API bearer token, the client makes another request (again from the server) to a configured API endpoint on your application (authenticating with the bearer token) to retrieve information about the user.

Configuration

The configuration for the OAuth2 server is located in the config/auth.config.js file, in the servers.oauth2 key. Note that this is NOT the same as the sources.example_oauth key.

oauth2: {
    enable: env('OAUTH2_SERVER_ENABLE', false),

    // Grants that are available to clients. Supported types are authorization_code, password
    grants: ['authorization_code'],

    // Built in data retrieval endpoints. These are protected by user-specific OAuth2 tokens
    built_in_endpoints: {

        // Get the token user's data
        user: {
            enable: env('OAUTH2_SERVER_ENABLE', true),

            // Fields to return to the endpoint
            // The keys are the keys in the request. The values are the keys in the user.
            fields: {
                username: 'uid',
                id: 'uuid',

                // Data is a special key. It's key-value pairs are included,
                // unserialized, from the user's JSON data.
                data: {
                    // Fields stored in serialized data can be included here:
                    // special_field: 'some_json_data_field',
                },
            },
        },
    },
},

Here we see a relatively straightforward implementation for the OAuth2 server. Let's walk through the configuration options in turn:

OAuth2 Server Options

enable (default: false)

Set to true to allow client applications to authenticate with your application using the OAuth2 server.

grants (default: ['authorization_code'])

An array of the enabled grant types. As of now, the authorization_code is the only supported grant.

built_in_endpoints

An object specifying the configuration for various built-in API endpoints for OAuth2 authentication.

built_in_endpoints.user

This endpoint provides information about the user associated with the provided bearer token.

built_in_endpoints.user.enable

Set to true to enable this endpoint.

built_in_endpoints.user.fields

An object mapping fields sent in the response to fields on the module:flitter-auth/model/User~BaseUser model.

built_in_endpoints.user.fields.data

This is a special field. Any mappings here will be looked up from the User's serialized JSON and sent as unserialized values.

Client IDs and Client Secrets

By default, Flitter Auth provides no interface for generating client IDs and client secrets for applications to use with this server. However, it's a fairly straightforward process. Here's how to do it from the Flitter Shell:

> Client = _services.models.get('auth::Oauth2Client')
> client = new Client({ name: 'Some Application', grants: ['authorization_code'], redirectUris: ['http://an.array.of/valid/redirect/uris'] })
> await client.save()
> client.clientID // 'fa6bd14a-e643-403c-81c0-af73ec19860d'
> client.clientSecret // '0865a4de-7b4e-438b-a20b-cb326459d5ee'

Bearer Token Middleware

You can protect routes to be accessible only by valid bearer tokens by applying the auth:Oauth2TokenOnly middleware to the route. This will inject some user info in the req.user element, which you can then use to query the whole user object.

Built-In User API

Flitter Auth's OAuth2 server comes with a simple built-in API for accessing user data using a bearer token, as detailed above. This API endpoint is accessible at:

https://you.app.url/auth/service/oauth2/data/user