Custom Login UI
With Quasr you can build and use your own login UI while still benefiting from using the standard integration mechanism of OpenID Connect under the hood. High-level the process is as follows:
Build your own login UI using the Quasr Authentication API.
Configure clients in Quasr to use your login UI instead of the default Hosted Login UI.
Test and validate the complete flow with your own login UI (using a client test option).
Connect your app using OAuth 2.0 / OpenID Connect 1.0 identical to Hosted Login UI.
Step 1 - Build Your Own Login UI
First of all please get familiar with the Hosted Login UI as it will give you a good understanding of all of the steps involved and how a login / signup experience could look like. Your custom login UI will received following query parameters:
client_idthe ID of the client initiating the flow (i.e. the application from where the user is coming or trying to access)scopethe scopes the client is requesting (this could be API scopes to obtain access to user details, the Quasr API or for your own API) — the scopes are in 1 string and space-separated.client_labelthe label of the client initiating the flowother OAuth 2.0 parameters for which there's not need to understand them — please capture these so they can be used in step 6
This guide only details the happy flow — please be mindful that much related to building a good login UI has to do with dealing with unhappy flows. Hence significant more effort will be required in creating a customer-ready login UI.

1. Get Available Controls / Factors (optional)
This step is optional as you could choose to hard-code this info in your login UI. The first call will give you information on what controls are required / optional, whether they require consent or permission, and what score you'll need to achieve to obtain (or grant them). The other call gives you which factors are available for login or signup that the user can choose from.
Get public controls for a specific client.
GET https://{tenant_id}.api.quasr.io/controls
Fetch control information for a specific client.
Query Parameters
client_id*
UUID
ID of the client
Get public factors for a specific tenant.
GET https://{tenant_id}.api.quasr.io/factors
Fetch the available factors for login / signup.
These APIs are highly cached (up to 24 hours) and don't count towards your metrics.
2. Initial Login / Signup
This step is required and the core of the Authentication API. This call will allow an unknown user to login or signup with your tenant.
Public signup for new users.
POST https://{tenant_id}.api.quasr.io/controls
Initiate signup with one or more controls.
Query Parameters
client_id*
UUID
ID of the client
Request Body
id*
UUID
ID of the control
consent
Boolean
consent (for controls that require consent to be provided)
label
String
label to attach to consent
expires_in
String
option to time-box consent
Public login for registered accounts.
POST https://{tenant_id}.api.quasr.io/factors
Initiate login with a chosen factor.
Request Body
id*
UUID
ID of the factor
input
String
user input for the factor (depends on chosen factor type)
Input is not always required depending on the chosen factor type:
oauth2:xno input neededsecret:iduser input required for login / recommended for signup (in case missing it will generate an identifier for you during signup, though the generated identifier may be hard to memorize for humans so it's not recommended)otpuser input required
To avoid invalid input errors please look at the regex specified on the factor in step 1. Our Hosted Login UI uses this field to asses the input in the front-end before passing it on towards the API.
The body in above calls is an array object as follows:
Let's zoom in a bit on the returned response.
We recommend storing the session_token in browser LocalStorage.
In case the result is PENDING you have to perform the following:
If this occurs at login you'll not receive a
session_tokenand you'll need to call this API again but this time as instructed for the specific factor.If this occurs at signup you'll receive a
session_tokenand you can continue this guide.
If you want to support an invite flow, the invite_token returned upon account creation is basically a session token resembling a signup with no factors (and hence zero score). Hence you can just accept the token from the user and continue with step 3.
3. Get Available Controls / Factors (optional)
This step depends on whether you need to continue building up your score.
Get personalized controls for a specific client.
GET https://{tenant_id}.api.quasr.io/controls
Fetch control information for a specific client.
Query Parameters
client_id*
UUID
ID of the client
Headers
Authorization*
JWT
session token
Get personalized factors for a specific tenant.
GET https://{tenant_id}.api.quasr.io/factors
Fetch the available factors for login / signup.
Headers
Authorization*
JWT
session token
Notice that the call format of these APIs are identical to that of step 1 - the only difference is that it's now called with the session_token in the Authorization header.
4. Step-Up Login / Signup (optional)
This step is required in case you need to increase the user's score (for example to obtain or grant certain controls). This call will allow an identified / registered user to continue login or signup with your tenant.
Continue login for a registered account.
POST https://{tenant_id}.api.quasr.io/factors
Continue login with a chosen enrollment.
Headers
Authorization*
String
Request Body
id*
String
ID of the enrollment
input
String
user input for the factor (depends on chosen factor type)
Continue signup for a new user.
POST https://{tenant_id}.api.quasr.io/factors
Continue signup with a chosen factor.
Headers
Authorization*
String
session token
Request Body
id*
String
ID of the factor
input
String
user input for the factor (depends on chosen factor type)
label
String
label to attach to enrollment if succesfull
The body in above calls is an array object as follows (currently only 1 entry is supported):
Notice that the call format of this API is identical to that of step 2 - the only difference is that it's now called with the session_token in the Authorization header.
The output is identical to that of step 2 — make sure to replace your current session_token with the new one returned in this call.
5. Obtain / Grant Consent
This step is required and part of the core of the Authentication API. This call will allow an identified / registered user to obtain and/or grant consent consent for the client application. This step checks the following:
The user has accepted all required legal controls (e.g. Terms & Conditions).
The user has achieved the required score to grant scopes to the client application.
The user has permission to grant specific scopes to the client application (think admin access).
The user has provided consent to grant scopes to the client application (only for external one).
Obtain and/or grant consent for a specific client.
POST https://{tenant_id}.api.quasr.io/controls
Obtain and/or grant consent for a specific client.
Query Parameters
client_id*
UUID
ID of the client
Headers
Authorization*
JWT
session token
Request Body
id*
UUID
ID of the control
consent
Boolean
consent (for controls that require consent to be provided)
label
String
label to attach to consent
expires_in
String
option to time-box consent
Let's zoom in a bit on the returned response.
It is especially important as signup to replace the existing session_token with the one returned in this call. As the new session will be a login session with a longer lifetime, else the user will be asked to log back in shortly after registration.
6. Finish
This step is required in order to finish the login/signup flow correctly. Make sure you have obtained a consent_token in step 5. This call will result in redirect you'll need to follow (HTTP status 302).
Request access to a specific client.
GET https://{tenant_id}.api.quasr.io/oauth2/authorize
Finish the login/signup flow with a consent token.
Query Parameters
client_id*
String
ID of the client
response_type*
String
pass on as provided
state
String
pass on if provided
nonce
String
pass on if provided
redirect_uri
String
pass on if provided
code_challenge
String
pass on if provided
code_challenge_method
String
pass on if provided
consent*
String
consent token
scope
String
pass on if provided
Each consent token can only be used exactly once.
Step 2 - Configure Login URI
As your login UI is now ready to handle incoming requests you must configure Quasr to start using it. This is currently only possible to be configured on each client (application) individually.
Go to Accounts, find the client, click edit, go to OAuth2 Settings and set your Login URL.

Step 3 - Test Login Flow
First make sure that the authorization_code grant type is enabled for you client. In the account list in the Quasr Tenant Admin UI you'll now see the option to test your client. Triggering the flow as such will include two more query parameters to your login UI:
prompt=loginthis is an official OAuth 2.0 parameter, indicating that your login UI should ask the user to login regardless of whether they already have a session (it's not required to support this parameter)mode=testthis is a Quasr parameter and is used by the Hosted Login UI to bypass the cache, recall that certain API calls are highly cached, allowing you to more quickly see tenant changes (it's not required to support this parameter)

Currently the pop-up dialog is not using the configured login URL but defaulting to the hosted login UI for your tenant, hence please make sure to edit the URL before testing.

Last updated