UNPKG

16.6 kBMarkdownView Raw
1# @auth0/auth0-spa-js
2
3Auth0 SDK for Single Page Applications using [Authorization Code Grant Flow with PKCE](https://auth0.com/docs/api-auth/tutorials/authorization-code-grant-pkce).
4
5[![CircleCI](https://circleci.com/gh/auth0/auth0-spa-js.svg?style=svg)](https://circleci.com/gh/auth0/auth0-spa-js)
6![Release](https://img.shields.io/github/v/release/auth0/auth0-spa-js)
7[![Codecov](https://img.shields.io/codecov/c/github/auth0/auth0-spa-js)](https://codecov.io/gh/auth0/auth0-spa-js)
8![Downloads](https://img.shields.io/npm/dw/@auth0/auth0-spa-js)
9[![License](https://img.shields.io/:license-mit-blue.svg?style=flat)](https://opensource.org/licenses/MIT)
10
11## Table of Contents
12
13- [Documentation](#documentation)
14- [Installation](#installation)
15- [Getting Started](#getting-started)
16- [Contributing](#contributing)
17- [Support + Feedback](#support--feedback)
18- [Frequently Asked Questions](#frequently-asked-questions)
19- [Vulnerability Reporting](#vulnerability-reporting)
20- [What is Auth0](#what-is-auth0)
21- [License](#license)
22
23## Documentation
24
25- [Documentation](https://auth0.com/docs/libraries/auth0-spa-js)
26- [API reference](https://auth0.github.io/auth0-spa-js/)
27- [Migrate from Auth0.js to the Auth0 Single Page App SDK](https://auth0.com/docs/libraries/auth0-spa-js/migrate-from-auth0js)
28
29## Installation
30
31From the CDN:
32
33```html
34<script src="https://cdn.auth0.com/js/auth0-spa-js/1.21/auth0-spa-js.production.js"></script>
35```
36
37Using [npm](https://npmjs.org):
38
39```sh
40npm install @auth0/auth0-spa-js
41```
42
43Using [yarn](https://yarnpkg.com):
44
45```sh
46yarn add @auth0/auth0-spa-js
47```
48
49## Getting Started
50
51### Auth0 Configuration
52
53Create a **Single Page Application** in the [Auth0 Dashboard](https://manage.auth0.com/#/applications).
54
55> **If you're using an existing application**, verify that you have configured the following settings in your Single Page Application:
56>
57> - Click on the "Settings" tab of your application's page.
58> - Ensure that "Token Endpoint Authentication Method" under "Application Properties" is set to "None"
59> - Scroll down and click on the "Show Advanced Settings" link.
60> - Under "Advanced Settings", click on the "OAuth" tab.
61> - Ensure that "JsonWebToken Signature Algorithm" is set to `RS256` and that "OIDC Conformant" is enabled.
62
63Next, configure the following URLs for your application under the "Application URIs" section of the "Settings" page:
64
65- **Allowed Callback URLs**: `http://localhost:3000`
66- **Allowed Logout URLs**: `http://localhost:3000`
67- **Allowed Web Origins**: `http://localhost:3000`
68
69> These URLs should reflect the origins that your application is running on. **Allowed Callback URLs** may also include a path, depending on where you're handling the callback (see below).
70
71Take note of the **Client ID** and **Domain** values under the "Basic Information" section. You'll need these values in the next step.
72
73### Creating the client
74
75Create an `Auth0Client` instance before rendering or initializing your application. You should only have one instance of the client.
76
77```js
78import createAuth0Client from '@auth0/auth0-spa-js';
79
80//with async/await
81const auth0 = await createAuth0Client({
82 domain: '<AUTH0_DOMAIN>',
83 client_id: '<AUTH0_CLIENT_ID>',
84 redirect_uri: '<MY_CALLBACK_URL>'
85});
86
87//with promises
88createAuth0Client({
89 domain: '<AUTH0_DOMAIN>',
90 client_id: '<AUTH0_CLIENT_ID>',
91 redirect_uri: '<MY_CALLBACK_URL>'
92}).then(auth0 => {
93 //...
94});
95
96//or, you can just instantiate the client on it's own
97import { Auth0Client } from '@auth0/auth0-spa-js';
98
99const auth0 = new Auth0Client({
100 domain: '<AUTH0_DOMAIN>',
101 client_id: '<AUTH0_CLIENT_ID>',
102 redirect_uri: '<MY_CALLBACK_URL>'
103});
104
105//if you do this, you'll need to check the session yourself
106try {
107 await auth0.getTokenSilently();
108} catch (error) {
109 if (error.error !== 'login_required') {
110 throw error;
111 }
112}
113```
114
115### 1 - Login
116
117```html
118<button id="login">Click to Login</button>
119```
120
121```js
122//with async/await
123
124//redirect to the Universal Login Page
125document.getElementById('login').addEventListener('click', async () => {
126 await auth0.loginWithRedirect();
127});
128
129//in your callback route (<MY_CALLBACK_URL>)
130window.addEventListener('load', async () => {
131 const redirectResult = await auth0.handleRedirectCallback();
132 //logged in. you can get the user profile like this:
133 const user = await auth0.getUser();
134 console.log(user);
135});
136
137//with promises
138
139//redirect to the Universal Login Page
140document.getElementById('login').addEventListener('click', () => {
141 auth0.loginWithRedirect().catch(() => {
142 //error while redirecting the user
143 });
144});
145
146//in your callback route (<MY_CALLBACK_URL>)
147window.addEventListener('load', () => {
148 auth0.handleRedirectCallback().then(redirectResult => {
149 //logged in. you can get the user profile like this:
150 auth0.getUser().then(user => {
151 console.log(user);
152 });
153 });
154});
155```
156
157### 2 - Calling an API
158
159```html
160<button id="call-api">Call an API</button>
161```
162
163```js
164//with async/await
165document.getElementById('call-api').addEventListener('click', async () => {
166 const accessToken = await auth0.getTokenSilently();
167 const result = await fetch('https://myapi.com', {
168 method: 'GET',
169 headers: {
170 Authorization: `Bearer ${accessToken}`
171 }
172 });
173 const data = await result.json();
174 console.log(data);
175});
176
177//with promises
178document.getElementById('call-api').addEventListener('click', () => {
179 auth0
180 .getTokenSilently()
181 .then(accessToken =>
182 fetch('https://myapi.com', {
183 method: 'GET',
184 headers: {
185 Authorization: `Bearer ${accessToken}`
186 }
187 })
188 )
189 .then(result => result.json())
190 .then(data => {
191 console.log(data);
192 });
193});
194```
195
196### 3 - Logout
197
198```html
199<button id="logout">Logout</button>
200```
201
202```js
203import createAuth0Client from '@auth0/auth0-spa-js';
204
205document.getElementById('logout').addEventListener('click', () => {
206 auth0.logout();
207});
208```
209
210You can redirect users back to your app after logging out. This URL must appear in the **Allowed Logout URLs** setting for the app in your [Auth0 Dashboard](https://manage.auth0.com):
211
212```js
213auth0.logout({
214 returnTo: 'https://your.custom.url.example.com/'
215});
216```
217
218### Data caching options
219
220The SDK can be configured to cache ID tokens and access tokens either in memory or in local storage. The default is in memory. This setting can be controlled using the `cacheLocation` option when creating the Auth0 client.
221
222To use the in-memory mode, no additional options need are required as this is the default setting. To configure the SDK to cache data using local storage, set `cacheLocation` as follows:
223
224```js
225await createAuth0Client({
226 domain: '<AUTH0_DOMAIN>',
227 client_id: '<AUTH0_CLIENT_ID>',
228 redirect_uri: '<MY_CALLBACK_URL>',
229 cacheLocation: 'localstorage' // valid values are: 'memory' or 'localstorage'
230});
231```
232
233**Important:** This feature will allow the caching of data **such as ID and access tokens** to be stored in local storage. Exercising this option changes the security characteristics of your application and **should not be used lightly**. Extra care should be taken to mitigate against XSS attacks and minimize the risk of tokens being stolen from local storage.
234
235#### Creating a custom cache
236
237The SDK can be configured to use a custom cache store that is implemented by your application. This is useful if you are using this SDK in an environment where more secure token storage is available, such as potentially a hybrid mobile app.
238
239To do this, provide an object to the `cache` property of the SDK configuration.
240
241The object should implement the following functions. Note that all of these functions can optionally return a Promise or a static value.
242
243| Signature | Return type | Description |
244| -------------------------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
245| `get(key)` | Promise<object> or object | Returns the item from the cache with the specified key, or `undefined` if it was not found |
246| `set(key: string, object: any) ` | Promise<void> or void | Sets an item into the cache |
247| `remove(key)` | Promise<void> or void | Removes a single item from the cache at the specified key, or no-op if the item was not found |
248| `allKeys()` | Promise<string[]> or string [] | (optional) Implement this if your cache has the ability to return a list of all keys. Otherwise, the SDK internally records its own key manifest using your cache. **Note**: if you only want to ensure you only return keys used by this SDK, the keys we use are prefixed with `@@auth0spajs@@` |
249
250Here's an example of a custom cache implementation that uses `sessionStorage` to store tokens and apply it to the Auth0 SPA SDK:
251
252```js
253const sessionStorageCache = {
254 get: function (key) {
255 return JSON.parse(sessionStorage.getItem(key));
256 },
257
258 set: function (key, value) {
259 sessionStorage.setItem(key, JSON.stringify(value));
260 },
261
262 remove: function (key) {
263 sessionStorage.removeItem(key);
264 },
265
266 // Optional
267 allKeys: function () {
268 return Object.keys(sessionStorage);
269 }
270};
271
272await createAuth0Client({
273 domain: '<AUTH0_DOMAIN>',
274 client_id: '<AUTH0_CLIENT_ID>',
275 redirect_uri: '<MY_CALLBACK_URL>',
276 cache: sessionStorageCache
277});
278```
279
280**Note:** The `cache` property takes precedence over the `cacheLocation` property if both are set. A warning is displayed in the console if this scenario occurs.
281
282We also export the internal `InMemoryCache` and `LocalStorageCache` implementations, so you can wrap your custom cache around these implementations if you wish.
283
284### Refresh Tokens
285
286Refresh tokens can be used to request new access tokens. [Read more about how our refresh tokens work for browser-based applications](https://auth0.com/docs/tokens/concepts/refresh-token-rotation) to help you decide whether or not you need to use them.
287
288To enable the use of refresh tokens, set the `useRefreshTokens` option to `true`:
289
290```js
291await createAuth0Client({
292 domain: '<AUTH0_DOMAIN>',
293 client_id: '<AUTH0_CLIENT_ID>',
294 redirect_uri: '<MY_CALLBACK_URL>',
295 useRefreshTokens: true
296});
297```
298
299Using this setting will cause the SDK to automatically send the `offline_access` scope to the authorization server. Refresh tokens will then be used to exchange for new access tokens instead of using a hidden iframe, and calls the `/oauth/token` endpoint directly. This means that in most cases the SDK does not rely on third-party cookies when using refresh tokens.
300
301**Note** This configuration option requires Rotating Refresh Tokens to be [enabled for your Auth0 Tenant](https://auth0.com/docs/tokens/guides/configure-refresh-token-rotation).
302
303#### Refresh Token fallback
304
305In all cases where a refresh token is not available, the SDK falls back to the legacy technique of using a hidden iframe with `prompt=none` to try and get a new access token and refresh token. This scenario would occur for example if you are using the in-memory cache and you have refreshed the page. In this case, any refresh token that was stored previously would be lost.
306
307If the fallback mechanism fails, a `login_required` error will be thrown and could be handled in order to put the user back through the authentication process.
308
309**Note**: This fallback mechanism does still require access to the Auth0 session cookie, so if third-party cookies are being blocked then this fallback will not work and the user must re-authenticate in order to get a new refresh token.
310
311### Organizations
312
313[Organizations](https://auth0.com/docs/organizations) is a set of features that provide better support for developers who build and maintain SaaS and Business-to-Business (B2B) applications.
314
315#### Log in to an organization
316
317Log in to an organization by specifying the `organization` parameter when setting up the client:
318
319```js
320createAuth0Client({
321 domain: '<AUTH0_DOMAIN>',
322 client_id: '<AUTH0_CLIENT_ID>',
323 redirect_uri: '<MY_CALLBACK_URL>',
324 organization: '<MY_ORG_ID>'
325});
326```
327
328You can also specify the organization when logging in:
329
330```js
331// Using a redirect
332client.loginWithRedirect({
333 organization: '<MY_ORG_ID>'
334});
335
336// Using a popup window
337client.loginWithPopup({
338 organization: '<MY_ORG_ID>'
339});
340```
341
342#### Accept user invitations
343
344Accept a user invitation through the SDK by creating a route within your application that can handle the user invitation URL, and log the user in by passing the `organization` and `invitation` parameters from this URL. You can either use `loginWithRedirect` or `loginWithPopup` as needed.
345
346```js
347const url = new URL(invitationUrl);
348const params = new URLSearchParams(url.search);
349const organization = params.get('organization');
350const invitation = params.get('invitation');
351
352if (organization && invitation) {
353 client.loginWithRedirect({
354 organization,
355 invitation
356 });
357}
358```
359
360### Advanced options
361
362Advanced options can be set by specifying the `advancedOptions` property when configuring `Auth0Client`. Learn about the complete set of advanced options in the [API documentation](https://auth0.github.io/auth0-spa-js/interfaces/advancedoptions.html)
363
364```js
365createAuth0Client({
366 domain: '<AUTH0_DOMAIN>',
367 client_id: '<AUTH0_CLIENT_ID>',
368 advancedOptions: {
369 defaultScope: 'email' // change the scopes that are applied to every authz request. **Note**: `openid` is always specified regardless of this setting
370 }
371});
372```
373
374## Contributing
375
376We appreciate feedback and contribution to this repo! Before you get started, please see the following:
377
378- [Auth0's general contribution guidelines](https://github.com/auth0/open-source-template/blob/master/GENERAL-CONTRIBUTING.md)
379- [Auth0's code of conduct guidelines](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md)
380- [This repo's contribution guide](https://github.com/auth0/auth0-spa-js/blob/master/CONTRIBUTING.md)
381
382## Support + Feedback
383
384For support or to provide feedback, please [raise an issue on our issue tracker](https://github.com/auth0/auth0-spa-js/issues).
385
386## Frequently Asked Questions
387
388For a rundown of common issues you might encounter when using the SDK, please check out [the FAQ](https://github.com/auth0/auth0-spa-js/blob/master/FAQ.md).
389
390## Vulnerability Reporting
391
392Please do not report security vulnerabilities on the public GitHub issue tracker. The [Responsible Disclosure Program](https://auth0.com/whitehat) details the procedure for disclosing security issues.
393
394## What is Auth0?
395
396Auth0 helps you to easily:
397
398- implement authentication with multiple identity providers, including social (e.g., Google, Facebook, Microsoft, LinkedIn, GitHub, Twitter, etc), or enterprise (e.g., Windows Azure AD, Google Apps, Active Directory, ADFS, SAML, etc.)
399- log in users with username/password databases, passwordless, or multi-factor authentication
400- link multiple user accounts together
401- generate signed JSON Web Tokens to authorize your API calls and flow the user identity securely
402- access demographics and analytics detailing how, when, and where users are logging in
403- enrich user profiles from other data sources using customizable JavaScript rules
404
405[Why Auth0?](https://auth0.com/why-auth0)
406
407## License
408
409This project is licensed under the MIT license. See the [LICENSE](https://github.com/auth0/auth0-spa-js/blob/master/LICENSE) file for more info.