ra-auth-cognito React-Admin Authentication Provider
ra-auth-cognito is an authentication provider designed specifically for React-Admin applications, integrating seamlessly with AWS Cognito user pools. The current stable version is 2.0.0, which introduced compatibility with React-Admin v5. The package typically releases new major versions aligned with React-Admin's major updates, alongside minor and patch releases for features and bug fixes. Key differentiators include robust support for username/password authentication, OAuth flows via AWS Hosted UI, and multi-factor authentication (MFA) including TOTP. It provides specialized components and hooks, such as `Login` and `useCognitoLogin`, to manage the initial login process for users with temporary passwords. This library simplifies common Cognito integration challenges within React-Admin, allowing developers to handle user identity, group-based permissions, and various authentication flows directly within their admin interfaces. Users must be pre-registered in Cognito with an email for the system to function correctly.
Common errors
-
Auth error: Invalid session
cause The user's Cognito session has expired, they are unauthenticated, or they are trying to log in with a temporary password that requires a change, but the application isn't handling the temporary password flow.fixEnsure the application handles temporary password changes on first login (using `<Login>` component). If not a first login, the user needs to re-authenticate. Check network requests for more specific Cognito error codes. -
CORS error: Redirect URI mismatch
cause When using OAuth, the redirect URI configured in your `ra-auth-cognito` setup (or derived from your application's URL) does not match the allowed callback URLs specified in your AWS Cognito User Pool's App Client settings.fixVerify that the `hostedUIUrl` in your `CognitoAuthProvider` configuration (if using OAuth) and the 'Callback URLs' list in your Cognito App Client settings in the AWS console are identical, including scheme (http/https), hostname, and path. -
User is not confirmed.
cause The user account exists in Cognito but has not yet been confirmed (e.g., through email verification or admin confirmation).fixEither have the user complete the confirmation process (if email/SMS verification is enabled) or manually confirm the user in the AWS Cognito console. -
Missing required parameter UserPoolId
cause The `UserPoolId` or `ClientId` for the `CognitoUserPool` constructor (or `CognitoAuthProvider` options in OAuth mode) is missing or incorrectly provided.fixDouble-check that `UserPoolId` and `ClientId` environment variables or direct values are correctly set and passed to the `CognitoUserPool` constructor or `CognitoAuthProvider` options.
Warnings
- breaking Version 2.0.0 of `ra-auth-cognito` introduces breaking changes by updating its peer dependency to `react-admin` v5. Applications using `react-admin` v4 or older must remain on `ra-auth-cognito` v1.x.
- gotcha When using username/password authentication, AWS Cognito often requires users to change a temporary password on their first login. Failing to use the provided `<Login>` component or `useCognitoLogin` hook will result in a stuck user experience.
- gotcha All users attempting to sign in must first be added to the configured Cognito user pool and have a valid email address associated with their profile for the authentication flow to succeed.
- gotcha Configuring OAuth with AWS Hosted UI requires precise setup of the `hostedUIUrl`, `clientId`, and `userPoolId`, along with correctly configured redirect URLs in your Cognito App Client settings. An incorrect setup often leads to redirect failures or authentication errors.
- gotcha The `authProvider.getPermissions()` method returns an array of Cognito user groups. If your Cognito user pool does not use groups, or the user is not assigned to any, this method will return an empty array, potentially leading to incorrect authorization behavior in `react-admin`.
Install
-
npm install ra-auth-cognito -
yarn add ra-auth-cognito -
pnpm add ra-auth-cognito
Imports
- CognitoAuthProvider
const { CognitoAuthProvider } = require('ra-auth-cognito');import { CognitoAuthProvider } from 'ra-auth-cognito'; - Login
import Login from 'ra-auth-cognito/Login';
import { Login } from 'ra-auth-cognito'; - LoginForm
import { Login } from 'ra-auth-cognito/LoginForm';import { LoginForm } from 'ra-auth-cognito'; - useCognitoLogin
import { useCognitoLogin } from 'ra-auth-cognito';
Quickstart
import React from 'react';
import { Admin, Resource } from 'react-admin';
import { CognitoAuthProvider, Login } from 'ra-auth-cognito';
import { CognitoUserPool } from 'amazon-cognito-identity-js';
// Mock data provider and resources for demonstration
const dataProvider = {
getList: () => Promise.resolve({ data: [{ id: 1, title: 'Post 1' }], total: 1 }),
getOne: () => Promise.resolve({ data: { id: 1, title: 'Post 1' } }),
getMany: () => Promise.resolve({ data: [{ id: 1, title: 'Post 1' }] }),
getManyReference: () => Promise.resolve({ data: [{ id: 1, title: 'Post 1' }], total: 1 }),
update: () => Promise.resolve({ data: { id: 1, title: 'Post 1' } }),
updateMany: () => Promise.resolve({ data: [{ id: 1, title: 'Post 1' }] }),
create: () => Promise.resolve({ data: { id: 1, title: 'New Post' } }),
delete: () => Promise.resolve({ data: { id: 1, title: 'Post 1' } }),
deleteMany: () => Promise.resolve({ data: [{ id: 1, title: 'Post 1' }] })
};
const posts = { list: () => <div>Posts List</div>, edit: () => <div>Edit Post</div> };
// Ensure these environment variables are set in your .env file or build process
const userPoolId = process.env.REACT_APP_COGNITO_USERPOOL_ID ?? 'us-east-1_XXXXX';
const clientId = process.env.REACT_APP_COGNITO_APP_CLIENT_ID ?? 'XXXXXXXXXXXX';
const userPool = new CognitoUserPool({
UserPoolId: userPoolId,
ClientId: clientId
});
const authProvider = CognitoAuthProvider(userPool);
const App = () => {
if (!userPoolId || !clientId) {
console.error('Cognito UserPoolId or ClientId not set. Please check your environment variables.');
return <div>Configuration Error: Cognito details missing.</div>;
}
return (
<Admin
authProvider={authProvider}
dataProvider={dataProvider}
title="Example Admin"
loginPage={Login} // Use the provided Login component for temporary password handling
>
<Resource name="posts" {...posts} />
</Admin>
);
};
export default App;