Implicit Flow
The Flow
1. Initialize the Flux SDK
Initialize an instance of the Flux SDK using its
constructor. You must provide the clientId
that you received when you registered your app with Flux.
IMPORTANT: Do not provide your app's clientSecret
! Secrets should never be
provided in client-facing code.
You may also provide a redirectUri
here, which is required in later steps. It
can be provided or overridden later if need be, but in most cases, it is enough
to provide it at this stage.
var sdk = new FluxSdk('YOUR-CLIENT-ID', {
redirectUri: 'https://your-app.com/auth_callback'
};
2. Storing Credentials
Your app will need a way to store and access user credentials, such as localStorage.
For example:
function getFluxCredentials() {
return JSON.parse(localStorage.getItem('fluxCredentials') || {});
}
function setFluxCredentials(credentials) {
localStorage.setItem('fluxCredentials', JSON.stringify(credentials);
}
3. Create unique state and nonce values
These values are used to protect your users from cross-site request forgery (CSRF)) and replay attacks.
To ensure that they are sufficiently secure, both values should be unique (one per user session) and computationally difficult to guess.
For example:
function generateRandomToken() {
var tokenLength = 24;
var randomArray = [];
var characterSet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
for (var i = 0; i < tokenLength; i++) {
randomArray.push(Math.floor(Math.random() * tokenLength));
}
return btoa(randomArray.join('')).slice(0, 48);
}
function getState() {
var state = localStorage.getItem('state') || generateRandomToken();
localStorage.setItem('state', state);
return state;
}
function getNonce() {
var nonce = localStorage.getItem('nonce') || generateRandomToken();
localStorage.setItem('nonce', nonce);
return nonce;
}
NOTE:
Math.random
is not cryptographically secure. Depending on what browsers you need to support
and how comfortable you feel using JavaScript packages, we suggest using
window.crypto.getRandomValues()
or a package from npm.
4. Request authorization
Next, send the user to Flux to give your app consent to access their information.
We provide the helper method
getAuthorizeUrl
to facilitate this
process. This method requires the state and nonce values generated in the
previous step as well as an HTTP endpoint (redirectUri
) that is configured to
handle Flux's response. If you supplied a redirectUri
when you initialized the
SDK and don't need to override it, you do not need to provide it again.
var credentials = getFluxCredentials();
if (!credentials) {
// Clear local storage in case there are old state or nonce values
localStorage.clear();
if (!window.location.hash.match(/access_token/)) {
window.location.replace(sdk.getAuthorizeUrl(getState(), getNonce()));
}
// ...
}
5. Retrieve an access token and user information
From the endpoint specified as the redirectUri
by the previous step, use the
helper method exchangeCredentials
to
exchange the data returned by Flux from the previous step for an access token
and user information. You must again provide the state and nonce from
step 2. If you specified a redirectUri
in
step 3, you must specify it again here.
In return, you should receive a promise that resolves to the user's credentials](../../Glossary.md#credentials), including the access token, their basic information, their refresh token, and when the token expires. Most parts of the returned credentials are required by subsequent requests and should be stored, e.g., in the user's session.
Note that exchangeCredentials
handles details such as confirming that the
response contains the correct state, nonce, and an appropriately signed ID token
for you. We will throw an error if we encounter anything suspicious. If you have
any questions or concerns about this, please let us know!
var credentials = getFluxCredentials();
if (!credentials) {
// ...
if (window.location.hash.match(/access_token/) {
sdk.exchangeCredentials(getState(), getNonce())
.then(function(credentials) {
setFluxCredentials(credentials);
})
.then(function() {
// redirect somewhere else
});
}
}
6. Use the user's credentials in later endpoints
Now the fun begins! Use the credentials received in step 4 to access other endpoints from the Flux API, such as the user's projects.
// ...
var credentials = getFluxCredentials();
if (!credentials) {
redirect('/login');
} else {
var user = sdk.getUser(credentials);
user.listProjects()
.then(function(projects) {
// do something interesting!
});
}