Rather than implement support for specific OAuth2 providers (with, for example, a GitHubProvider
/GoogleProvider
/&c.), Flitter Auth ships with a generic Oauth2Provider
which supports the authorization_code
OAuth2 method. The idea is that the configuration for the OAuth2 provider in Flitter is fine-grained enough that it should be adaptable to work with most OAuth2 providers.
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 that provider, the provider's application redirects the user back to a specific endpoint on your application with a special token known as an authorization code. Flitter 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 the provider application.
Using that API bearer token, Flitter makes another request (again from the server) to a configured API endpoint on the provider application (authenticating with the bearer token) to retrieve information about the user. That information is then loaded into the module:flitter-auth/model/User~BaseUser model.
Configuration
Flitter Auth ships with an example config for an OAuth2 provider. This config provides an example allowing users to "Sign-In With GitHub." This means that the users authenticate with GitHub, GitHub issues Flitter an auth token, then Flitter uses that token to request the user data from api.github.com
, populating the User model.
Here's the example:
example_oauth: {
type: 'Oauth2Provider',
enable: env('AUTH_OAUTH2_ENABLE', false),
source_name: env('AUTH_OAUTH2_SOURCE_NAME', 'GitHub'),
source_client_id: env('AUTH_OAUTH2_CLIENT_ID'),
source_client_secret: env('AUTH_OAUTH2_CLIENT_SECRET'),
// Login page destination where the user will be redirected to on login
// %c will be interpolated with the client id
// %r will be interpolated with the redirect callback url
// NOTE: This url is the same as the login page - /auth/oauth2/login
source_login_page: env('AUTH_OAUTH2_LOGIN_REDIRECT', 'https://github.com/login/oauth/authorize?client_id=%c'),
// Information about the OAuth2 Callback
callback: {
// URL query parameter name with the authorization_code token
// e.g. ?code=XXXXXXXXXX
token_key: 'code',
},
// Information about the endpoint flitter-auth will use to redeem
// the authorization_code token for a bearer token
source_token: {
endpoint: 'https://github.com/login/oauth/access_token',
// Field name where the authorization_code token will be specified in the request
token_key: 'code',
// Field name for the client id
client_id_key: 'client_id',
// Field name for the client secret
client_secret_key: 'client_secret',
// Field name for the grant_type ('authorization_type')
grant_type_key: 'grant_type',
// Field name where the bearer token will be specified in the response
response_token_key: 'access_token',
},
// Information about the endpoint flitter-auth will use to get
// user information after it retrieves a bearer token
user_data: {
endpoint: 'https://api.github.com/user',
method: 'get', // 'get' or 'post' only
// In the response data, what key is the user data in?
// e.g. if 'data', then {'data': { ... }}
// Set falsy to assume the data exists in the root: { ... }
// data_root: 'data',
// Value that prefixes the token in the 'Authorization: ' header.
// e.g. 'token ' would mean 'token a0fw93ja0w93ja093wj'
// 'Bearer ' would be 'Bearer 0329j0239dj209j3209jd'
token_prefix: 'token ',
// Mapping of user model attributes to OAuth2 return data from the endpoint
// Note that uuid is not allowed, and uid is required
attributes: {
uid: 'login',
},
},
},
This creates an auth provider called example_oauth
that loads most of its parameters from the environment. Let's look at each of these parameters in turn:
OAuth2 Parameters
type (default: Oauth2Provider
)
This is the name of the provider class to use. For OAuth, it will always be Oauth2Provider
.
enable (default: false
)
If true, users will be allowed to authenticate with this provider.
source_name
The human-readable display name for the authentication provider. In this case, that readable name is "GitHub".
source_client_id
This is the unique identifier for your application. This is issued by the target provider. For example, you would generate a client secret in your GitHub settings.
source_client_secret
This is the unique secret for your application. This is passed along when the server requests the user's bearer to prove that the server is legit. This should be kept... well, secret.
source_login_page
This is the URL where users will be redirected to sign in with the provider application. All references to %c
in this string will be replaced with the client_id
. All references to %r
will be replaced with the URL the provider application should call back to once the authentication has completed.
callback
An object containing information about the callback that occurs when a user has successfully authenticated with the provider application.
callback.token_key
This is the key name of the field on the request where the authorization code will be stored when the client request is redirected.
source_token
An object containing information telling Flitter how to exchange the authorization code for a bearer token.
source_token.endpoint
URL of the API endpoint to call to redeem the auth code.
source_token.token_key
Name of the field in the request where the auth code should be specified.
source_token.client_id_key
Name of the field in the request where the client ID should be specified.
source_token.client_secret_key
Name of the field in the request where the client secret should be specified.
source_token.grant_type_key
Name of the field in the request where the grant type should be specified. This is always authorization_code
.
source_token.response_token_key
Name of the field in the response where the bearer token will be specified.
user_data
After retrieving the bearer token, Flitter Auth must make a request to some endpoint to get user information. This is an object containing information for making that request and parsing the response.
user_data.endpoint
URL of the API endpoint to call to fetch the user data.
user_data.method
What request method? get
or post
only!
user_data.token_prefix
Specifies the prefix before the token in the Authorization
header. E.g. token 2309j2093dj2093j
or Bearer aw09ejf0w9ej0f9sdjfiosdkjf
or blank to disable prefix.
user_data.data_root
If the user data is returned nested in a property of the request, specify that property here (e.g. data
). If the user data is returned in the root of the request, don't set this value.
user_data.attributes
An object mapping fields on the module:flitter-auth/model/User~BaseUser model to the fields on the response.
user_data.attributes.uid
This mapping is REQUIRED and must be provided by the configuration.
OAuth2 Callback URL
Provider applications redirect the user back to a specific URL once authentication with that provider is successful. For Flitter Auth, this is the URL of the login page:
https://your.app.url/auth/PROVIDER NAME/login