You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -7,22 +7,35 @@ title: "Writing An Auth Provider"
7
7
8
8
React-admin can use any authentication backend, but you have to write an adapter for it. This adapter is called an `authProvider`. The `authProvider` is a simple object with methods that react-admin calls to handle authentication and authorization.
9
9
10
-
## AuthProvider Interface Overview
10
+
## Auth Provider Methods
11
11
12
12
React-admin expect an `authProvider` to implement the following methods:
13
13
14
14
```tsx
15
15
const authProvider = {
16
-
// required methods
16
+
// REQUIRED
17
+
// send username and password to the auth server and get back credentials
18
+
// (for login / password flow)
17
19
async login(params) {/* ... */},
20
+
// when the dataProvider returns an error, check if this is an authentication error
18
21
async checkError(error) {/* ... */},
22
+
// when the user navigates, make sure that their credentials are still valid
19
23
async checkAuth(params) {/* ... */},
24
+
// remove local credentials and notify the auth server that the user logged out
20
25
async logout() {/* ... */},
21
-
// optional methods
26
+
27
+
// OPTIONAL
28
+
// get the user's profile (id, fullName, avatar)
22
29
async getIdentity() {/* ... */},
23
-
async handleCallback() {/* ... */}, // for third-party authentication only
24
-
async canAccess(params) {/* ... */}, // for authorization only
25
-
async getPermissions() {/* ... */}, // for authorization only
30
+
// process authentication callback from third-party providers
31
+
// (for third-party authentication flow)
32
+
async handleCallback() {/* ... */},
33
+
// check authorization for an action over a resource
Once an admin has an `authProvider`, react-admin enables a new page on the `/login` route, which displays a login form.
81
99
82
100

83
101
84
102
Upon submission, the login page calls the `authProvider.login()` method with the login data as parameter. React-admin expects this async method to return if the login data is correct, and to throw an error if it's not.
85
103
86
-
For instance, to query an authentication route via HTTPS and store the user credentials (a token) in local storage, configure the `authProvider` as follows:
104
+
**Tip:** The `login` method will never be called if you rely solely on [third-party authentication](./Authentication.md#using-external-authentication-providers) flows (e.g. Auth0, Cognito, or any other OAuth-based service). In this case, you can provide a dummy implementation that always resolves.
105
+
106
+
Below is an example showing how to configure the `authProvider` to query an authentication route via HTTPS and store the user credentials (a token) in local storage:
87
107
88
108
```tsx
89
109
// in src/authProvider.js
@@ -129,7 +149,16 @@ const authProvider = {
129
149
};
130
150
```
131
151
132
-
### `checkError`
152
+
## `checkError`
153
+
154
+
|**Purpose**| Check if a dataProvider error is an authentication error |
155
+
|**Required**| Yes |
156
+
|**When to use**| Always |
157
+
|**On resolve**| - |
158
+
|**On reject**| Logs the user out and redirects to the login page (customizable) |
159
+
|**Request format**|`{ message: string, status: number, body: Object }` (error from the dataProvider) |
Redirecting to the login page whenever a REST response uses a 401 status code is usually not enough. React-admin keeps data on the client side, and could briefly display stale data while contacting the server - even after the credentials are no longer valid.
211
249
@@ -269,7 +307,18 @@ const authProvider = {
269
307
};
270
308
```
271
309
272
-
### `logout`
310
+
**Tip:**`checkAuth` won't be called for routes [allowing anonymous access](./Authentication.md#allowing-anonymous-access).
311
+
312
+
## `logout`
313
+
314
+
|**Purpose**| Log out the user from the backend and clean up authentication data |
315
+
|**Required**| Yes |
316
+
|**When to use**| Always |
317
+
|**On resolve**| Redirects to login page (customizable) |
318
+
|**On reject**| - |
319
+
|**Request format**| - |
320
+
|**Response format**| `string | false | void` route to redirect to after logout, defaults to `/login` |
321
+
|**Error format**| - |
273
322
274
323
If you enable authentication, react-admin adds a logout button in the user menu in the top bar (or in the sliding menu on mobile). When the user clicks on the logout button, this calls the `authProvider.logout()` method, and removes potentially sensitive data stored in [the react-admin Store](./Store.md). Then the user gets redirected to the login page. The two previous sections also illustrated that react-admin can call `authProvider.logout()` itself, when the API returns a 403 error or when the local credentials expire.
275
324
@@ -303,9 +352,18 @@ const authProvider = {
303
352
};
304
353
```
305
354
306
-
### `getIdentity`
355
+
**Tip**: If both `authProvider.checkAuth()` and `authProvider.logout()` return a redirect URL, the one from `authProvider.checkAuth()` takes precedence.
356
+
357
+
## `getIdentity`
307
358
308
-
Admin components often adapt their behavior based on the current user identity. For instance, a lock system may allow edition only if the lock owner is the current user. Another example is the user menu: it has to display the current user name and avatar.
Admin components often adapt their behavior based on the current user identity. For instance, a [lock system](https://react-admin-ee.marmelab.com/documentation/ra-realtime#locks) may allow edition only if the lock owner is the current user. Another example is the [user menu](./AppBar.md#usermenu): it has to display the current user name and avatar.
309
367
310
368
React-admin delegates the storage of the connected user identity to the `authProvider`. If it exposes a `getIdentity()` method, react-admin will call it to read the user details.
311
369
@@ -326,7 +384,7 @@ React-admin uses the `fullName` and the `avatar` (an image source, or a data-uri
326
384
327
385

328
386
329
-
**Tip**: You can use the `id` field to identify the current user in your code, by calling the `useGetIdentity` hook:
387
+
**Tip**: You can use the `id` field to identify the current user in your code, by calling the [`useGetIdentity`](./useGetIdentity.md) hook:
This method is used when integrating a third-party authentication provider such as [Auth0](https://auth0.com/). React-admin provides a route at the `/auth-callback` path, to be used as the callback URL in the authentication service. After logging in using the authentication service, users will be redirected to this route. The `/auth-callback` route calls the `authProvider.handleCallback` method on mount.
Once `handleCallback` returns, react-admin redirects the user to the home page, or to the location found in `localStorage.getItem(PreviousLocationStorageKey)`. In the above example, `authProvider.checkAuth()` sets this location to the page the user was trying to access.
393
462
394
463
You can override this behavior by returning an object with a `redirectTo` property, as follows:
@@ -408,7 +477,16 @@ const authProvider = {
408
477
};
409
478
```
410
479
411
-
### `canAccess`
480
+
**Tip:** If you rely solely on third-party authentication flows, the `authProvider.login()` method will never be called. In this case you can simply provide a dummy implementation that always resolves.
481
+
482
+
## `canAccess`
483
+
484
+
|**Purpose**| Check authorization for an action over a resource |
485
+
|**Required**| No |
486
+
|**When to use**| For [Access Control](./Permissions.md#access-control) style Authorization |
React-admin has built-in [Access Control](./Permissions.md#access-control) features that you can enable by implementing the `authProvider.canAccess()` method. It receives a permissions object with the following properties:
414
492
@@ -452,7 +530,14 @@ Check the [Access Control documentation](./Permissions.md#access-control) for mo
452
530
**Tip**: [The Role-Based Access Control (RBAC) module](./AuthRBAC.md) allows fined-grained permissions in react-admin apps leveraging the `canAccess` method. Check [the RBAC documentation](./AuthRBAC.md) for more information.
453
531
454
532
455
-
### `getPermissions`
533
+
## `getPermissions`
534
+
535
+
|**Purpose**| Returns a boolean indicating whether the user can perform the provided action on the provided resource |
536
+
|**Required**| No |
537
+
|**When to use**| For [Permissions](./Permissions.md#permissions) style Authorization |
538
+
|**Request format**| params passed to `usePermissions()` -- empty for react-admin default routes |
539
+
|**Response format**|`any`|
540
+
|**Error format**|`Error`|
456
541
457
542
As an alternative to `canAccess()`, `getPermissions()` lets you return an arbitrary permissions object. This object can be used by React components to enable or disable UI elements based on the user's role.
458
543
@@ -472,50 +557,11 @@ React-admin doesn't use permissions by default, but it provides [the `usePermiss
472
557
473
558
Check the [Access Control documentation](./Permissions.md#permissions) for more information on how to use the `getPermissions` method.
474
559
475
-
## Request Format
476
-
477
-
React-admin calls the `authProvider` methods with the following params:
|`login`| Log a user in |`Object` whatever fields the login form contains |
482
-
|`checkError`| Check if a dataProvider error is an authentication error |`{ message: string, status: number, body: Object }` the error returned by the `dataProvider`|
483
-
|`checkAuth`| Check credentials before moving to a new route |`Object` whatever params passed to `useCheckAuth()` - empty for react-admin default routes |
484
-
|`logout`| Log a user out ||
485
-
|`getIdentity`| Get the current user identity ||
486
-
|`handleCallback`| Validate users after third party authentication service redirection ||
487
-
|`canAccess`| Check authorization for an action over a resource |`{ action: string, resource: string, record: object }`|
488
-
|`getPermissions`| Get the current user credentials |`Object` whatever params passed to `usePermissions()` - empty for react-admin default routes |
489
-
490
-
## Response Format
491
-
492
-
`authProvider` methods must return a Promise. In case of success, the Promise should resolve to the following value:
|`checkError`| Error is an auth error | `void | { redirectTo?: string, message?: string | boolean }` route to redirect to after logout, message to notify the user or `false` to disable notification |
513
-
|`checkAuth`| User is not authenticated | `void | { redirectTo?: string, message?: string }` route to redirect to after logout, message to notify the user |
514
-
|`logout`| Auth backend failed to log the user out |`void`|
515
-
|`getIdentity`| Auth backend failed to return identity |`Object` free format - returned as `error` when `useGetIdentity()` is called |
516
-
|`handleCallback`| Failed to authenticate users after redirection | `void | { redirectTo?: string, logoutOnFailure?: boolean, message?: string }` |
517
-
|`canAccess`| Auth backend failed to return authorization |`Object` free format - returned as `error` when `useCanAccess()` is called. |
518
-
|`getPermissions`| Auth backend failed to return permissions |`Object` free format - returned as `error` when `usePermissions()` is called. The error will be passed to `checkError`|
560
+
**Tip:** How to choose between `canAccess` and `getPermissions`? We recommend Access Control (i.e. `canAccess`) because it allows you to put the authorization logic in the `authProvider` rather than in the React code.
561
+
562
+
## Using External Authentication Providers
563
+
564
+
Instead of the built-in Login page, you can use an external authentication provider, like Auth0, Cognito, or any other OAuth-based service. See [Using External Authentication Providers](./Authentication.md#using-external-authentication-providers) for an example.
You can choose when to redirect users to the third-party authentication service, such as directly in the `AuthProvider.checkAuth()` method or when they click a button on a [custom login page](#customizing-the-login-component).
Note over RA:checkAuth()<br/>Auth0Client.isAuthenticated()
442
+
RA->>A:Auth0Client.loginWithRedirect()
443
+
Note over A: Login using Auth0 form
444
+
A->>RA: Redirects to /auth-callback<br/>(with token)
445
+
Note over RA:handleCallback()<br/>Auth0Client.handleRedirectCallback()
446
+
RA->>U: Redirects to /posts
447
+
```
448
+
Edited with https://mermaid.live/edit
449
+
{% endcomment %}
450
+
451
+
**Tip:** You can choose when to redirect users to the third-party authentication service, such as directly in the `AuthProvider.checkAuth()` method or when they click a button on a [custom login page](#customizing-the-login-component).
0 commit comments