Login.js
Login.js is a client-side library for Identity Service. It contains functions to trigger the authentication process and to include the IDS app switcher and profile page in your application.
Setup and Initialization
Let's get started integrating login.js into your project. To import the library, you can do it directly using our cdn:
<script src="https://id.vancoplatform.com/login.js"></script>
or you can can use npm:
npm install @vancoplatform/web-auth
WebAuth
WebAuth exposes functions to trigger the authentication process in a variety of ways. It is recommeneded for use in single page apps.
Initialization
Initialize a new instance of web auth as follows:
<script src="https://id.vancoplatform.com/login.js"></script>
...
<script>
var webAuth = new Vanco.Identity.login.WebAuth({
domain: 'id.vancoplatform.com',
clientID: 'YOUR_CLIENT_ID',
redirectUri: 'https://your-domain.com/'
});
</script>
or an example with React:
import { WebAuth } from "@vancoplatform/web-auth"
var webAuth = new WebAuth({
domain: "id.vancoplatform.com",
clientID: "YOUR_CLIENT_ID",
redirectUri: "https://your-domain.com/",
})
Available parameters
Paramter | Required | Description |
---|---|---|
domain | required | (String) The IDS domain. (id.vancoplatformstage.com for dev) |
clientID | required | (String) Your IDS client ID |
redirectUri | optional | (String) The default redirectUri used. |
scope | optional | (String) The default scopes(s) used by the application. These must be separated by a space. You can request any of the standard OIDC scopes about users, such as profile and email . Defaults to openid profile email . See the scopes documentation for more information. |
audience | optional | (String) The default audience to be used for requesting API access. |
responseType | optional | (String) The default responseType used. It can be any space seperated list of the values code , token , id_token . |
responseMode | optional | (String) This option is omitted by default. Can be set to 'form_post' in order to send the token or code to the redirectUri via a POST. Supported values are fragment and form_post . |
loginHint | optional | (String) A username/email for an account to which the login page will default. This does not force login to that account - the user can override it freely. |
Login
You can choose a method for login based on the type of auth you need in your application.
webAuth.authorize()
The authorize()
method can be used for logging in users via a page redirect. This method invokes the /oidc/authorize
endpoint and can take a variety of parameters via the options
object.
webAuth.authorize({
// Any additional options can go here
})
Available parameters
Parameters set in the constructor will be used by default, but can be overridden here:
Paramter | Required | Description |
---|---|---|
audience | optional | (String) The default audience to be used for requesting API access. |
scope | optional | (String) The scopes which you want to request authorization for. These must be separated by a space. You can request any of the standard OIDC scopes about users, such as profile and email . Defaults to openid profile email . See the scopes documentation for more information. |
responseType | optional | (String) It can be any space seperated list of the values code , token , id_token . |
clientID | optional | (String) Your IDS client ID |
redirectUri | optional | (String) The URL to which Identity Service will redirect the browser after authorization has been granted for the user. |
state | optional | (String) An arbitrary value that should be maintained across redirects. It is useful to mitigate CSRF attacks and for any contextual information (for example, a return URL) that you might need after the authentication process is finished. |
loginHint | optional | (String) A username/email for an account to which the login page will default. This does not force login to that account - the user can override it freely. |
acrValues | recommended | A value indicating the level of assurance (LOA) you require from IDS. This value determines how far IDS will go to be sure of the identity of the user logging in (e.g. a username and password, two-factor authentication, passwordless over SMS...). Defaults to username and password. For more details and a list of values, click here |
webAuth.popup.authorize()
For popup authentication, the popup.authorize()
method can be used. The popup.authorize()
method returns a JavaScript Promise that will resolve with the authorization result after the user has finished entering their credentials.
webAuth.popup
.authorize({
// Any additional options can go here
})
.then(function (result) {
// result will contain the result of the authorization.
// do something
})
.catch(function (err) {
console.log(err)
})
The page you call popup.authorize()
from must be listed as a valid redirect uri for your application.
webAuth.embedded.authorize()
For embedded authentication, the embedded.authorize()
method can be used. The embedded.authorize()
method returns a JavaScript Promise that will resolve with the authorization result after the user has finished entering their credentials.
You must also pass embedded.authorize()
a dom element. The embedded login page will be added to that dom element.
var loginContainer = document.getElementById("login")
webAuth.embedded
.authorize(
{
// Any additional options can go here
},
loginContainer
)
.then(function (result) {
// result will contain the result of the authorization.
// do something
})
.catch(function (err) {
console.log(err)
})
Note:
The page you call embedded.authorize()
from must be listed as a valid redirect uri for your application.
Extract the auth result and get user info
After authentication occurs, you can use the parseHash
method to parse a URL hash fragment when the user is redirected back to your application in order to extract the result of an authentication response. This is only necessary if you choose to use the default fragment
responseMode with a redirect-based authentication. You can handle this in a dedicated callback page that will redirect to your main application, or in-page.
The parseHash()
method takes an options
object that contains the following parameters:
Paramter | Required | Description |
---|---|---|
state | optional | (String) An opaque value the application adds to the initial request that is included when redirecting back to the application. This value is used by login.js to prevent CSRF attacks. |
nonce | optional | (String) Used to verify the ID Token. |
hash | optional | (String) The URL hash. If not provided, window.location.hash will be used by default |
The parseHash()
method returns a JavaScript Promise that will resolve with the authorization result. The contents of the authorization result will depend on which parameters where used. It can include:
Item | Description |
---|---|
accessToken | An Access Token for the API specified by the audience |
expiresIn | A string containing the expiration time (in seconds) of the accessToken |
idToken | An ID Token JWT containing user profile information |
webAuth
.parseHash({
// Any additional options can go here
})
.then(function (result) {
if (result != null) {
webAuth.client.userInfo(result.accessToken).then(function (user) {
// Now you have the user's information
})
}
})
.catch(function (err) {
console.log(err)
})
As shown above, the client.userInfo()
method can be called passing the returned accessToken
. It will make a request to the /api/userinfo
endpoint and return the user
object, which contains the user's information.
{
"sub": "6da3774c-da6a-4009-85c5-7920afd84af8",
"given_name": "John",
"family_name": "Doe",
"email": "[email protected]",
"email_verified": "true"
}
Using nonces
By default (and if responseType
contains id_token
), login.js will generate a random nonce
when you call webAuth.authorize()
, store it in local storage, and pull it out in webAuth.parseHash()
. The default behavior should work in most cases, but some use cases may require a developer to control the nonce
. If you want a developer generated nonce
, then you must provide it as an option to both webAuth.authorize()
and webAuth.parseHash()
.
webAuth.authorize({ nonce: "1234", responseType: "id_token" })
webAuth.parseHash({ nonce: "1234" }).then(/* ... */)
If you are using popup auth, the nonce must also be provided to webAuth.popup.callback()
webAuth.popup.callback({ nonce: "1234" })
ACR Values
Authentication Context Class Reference (ACR) values let you request a certain level of assurance (LOA) from IDS that the user being authenticated is actually who they say they are. In other words, this value is what determines how rigorous of a login process users will be required to go through. A low LOA would be passwordless SMS login, for example, where a user enters their phone number and is sent a code which they then enter to log in. A high LOA would be two-factor authentication, where a user not only has to provide their username and password, but also has to provide a code from an authentication app on their mobile device.
The values are related to each other in a heirarchical manner - higher LOAs satisfy the requirements of lower LOAs. Thus the value you request is a minimum requirement; for instance, if you request a LOA of username and password, but a user signs in with two-factor authentication, they will be successfully authorized. But if they try to sign in with a social auth provider, they will not be authorized.
This concept also applies to Single Sign On (SSO) between different applications using IDS. If someone is already logged in through IDS at a certain LOA, they will be authorized to access any application requesting a equal or lower LOA without needing to sign in again.
A full list of supported ACR values is below. You can send any one value with an authorization request.
Value | Description |
---|---|
ids:loa:none | Indicates that the user was signed in with only a username, email or phone #. No confidence. |
ids:loa:0 | Indicates that the user was signed in via a long-lived browser cookie (e.g. social auth) |
ids:loa:1 | Indicates that the user was signed in with a SMS code |
ids:loa:2 | Indicates that the user was signed in with a single factor, e.g. username/password or email code |
ids:loa:3 | Indicates the user was signed in with an app-based soft token and a minimum of two factors |
ids:loa:pci:nc | Indicates the user was signed in with a method compliant with PCI DSS third-party, non-consumer user. This enforces PCI requirements such as requiring users to update their passwords every 90 days, and disabling users after 90 days of inactivity. |
Profile
Profile allows you to embed Identity Service's user profile page in your application via an iframe. This means you can have a page inside your application for users to manage their IDS account, with next to no work on your part.
Initialization
Initialize a new instance of Profile as follows:
<script src="https://id.vancoplatform.com/login.js"></script>
...
<script>
var holder = $("#profile-iframe-holder")[0];
var profile = new Vanco.Identity.login.Profile({
element: holder,
url: 'https://id.vancoplatform.com',
tenant: 'my-tenant'
});
</script>
or an example with React:
import { Profile } from "@vancoplatform/web-auth"
var profile = new Profile({
element: holder,
url: "https://id.vancoplatform.com",
tenant: "my-tenant",
})
Available parameters
Paramter | Required | Description |
---|---|---|
element | required | (Object) a reference to the DOM element in which to render the profile page iframe |
url | required | (String) The URL to the Identity Server |
tenant | required | (String) Your tenant's unique identifier |
id | optional | (String) A value to set as the iframe's id attribute |
classname | optional | (String) A value to set as the iframe's class attribute |
Rendering
Once initialized, rendering the profile iframe is as simple as calling:
profile.render()
AppDrawer
AppDrawer allows you to embed Identity Service's app switcher in your application via an iframe.
Initialization
Initialize a new instance of AppDrawer as follows
<script src="https://id.vancoplatform.com/login.js"></script>
...
<script>
var holder = $("#app-drawer-iframe-holder")[0];
var drawer = new Vanco.Identity.AppDrawer({
element: holder,
url: 'https://idscdetest1000stor01.blob.core.windows.net/app-switcher/index.html',
idsurl: 'https://id.vancoplatform.com',
tenant: 'my-tenant'
});
</script>
or an example with React:
import { AppDrawer } from "@vancoplatform/web-auth";
var drawer = new AppDrawer({
element: <react ref here>,
url: 'https://idscdetest1000stor01.blob.core.windows.net/app-switcher/index.html',
idsurl: 'https://id.vancoplatform.com',
tenant: 'my-tenant'
});
Available parameters
Paramter | Required | Description |
---|---|---|
element | required | (Object) a reference to the DOM element in which to render the profile page iframe |
url | required | (String) The URL to the App Switcher |
idsurl | required | (String) The URL to the Identity Server |
tenant | required | (String) Your tenant's unique identifier |
id | optional | (String) A value to set as the iframe's id attribute |
classname | optional | (String) A value to set as the iframe's class attribute |
Rendering
Once initialized, rendering the app switcher iframe is as simple as calling:
var iframe = drawer.render()
The render function returns a reference to the iframe DOM element.
Other considerations
You will need to create a button for users to bring up the app switcher, probably somewhere in your site's header or menu. It is recommended to render the app switcher once in a hidden element on page load, and then toggle the visibility with a button for a seamless user experience.
The app switcher button should be consistent and recognizable across all applications. To that end, while the color and shape can be changed to fit your application, it should use this icon and look roughly like this button:
In addition, when toggling the iframe on, please use the following code to set the focus to the app switcher iframe, making it so that the user can simply start typing to search for their apps:
iframe.contentWindow.focus()