@criipto/verify-react
v6.0.1
Published
Verify SDK for React Single Page Applications
Readme
@criipto/verify-react
The Idura Verify React SDK lets you authenticate users with European eID providers supported by Idura.
The SDK uses the PKCE flow suitable for public clients.
Installation
npm install @criipto/verify-reactPrerequisites
You need an Idura application to initialize the SDK. If you haven't already, follow the dashboard setup guide to create one.
The SDK needs two values from your Idura application:
- your Idura domain
- your application client ID
Initialize the SDK
Initialize the SDK by wrapping your React app in CriiptoVerifyProvider:
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { CriiptoVerifyProvider } from '@criipto/verify-react';
import App from './App';
ReactDOM.render(
<CriiptoVerifyProvider
domain="{YOUR_IDURA_DOMAIN}"
clientID="{YOUR_IDURA_APPLICATION_CLIENT_ID}"
redirectUri={window.location.href}
>
<App />
</CriiptoVerifyProvider>,
document.getElementById('root'),
);The redirectUri you pass to CriiptoVerifyProvider is where Idura returns the user after login, and it must be registered as a redirect URL on your Idura application. The examples use window.location.href, but any route (e.g. a dedicated /callback path) works too.
Call the useCriiptoVerify hook
Inside a component wrapped by CriiptoVerifyProvider, call useCriiptoVerify to read the auth state and start a login.
const {
result,
claims,
error,
loginWithRedirect,
loginWithPopup,
logout,
isLoading,
isInitializing,
} = useCriiptoVerify();result: the login outcome,result.id_tokenorresult.codeon success and an error otherwiseclaims: the decodedid_tokenerror: configuration and login errorsloginWithRedirect/loginWithPopup: start a login with redirect or in a popup windowlogout: clear the session store and end the SSO sessionisLoading/isInitializing: whether the SDK is still working or starting up
Render login options
The SDK provides an AuthMethodSelector component that renders a method selector screen where your users can choose a login method.
By default, AuthMethodSelector shows one button per eID method enabled for your Idura application (Applications → your app → eIDs in the dashboard).
// src/App.js
import React from 'react';
import { useCriiptoVerify, AuthMethodSelector } from '@criipto/verify-react';
import '@criipto/verify-react/index.css'; // Import the stylesheet, or the buttons render unstyled.
export default function App() {
const { result, error } = useCriiptoVerify();
if (result?.id_token) {
return <pre>{JSON.stringify(result.id_token, null, 2)}</pre>;
}
return (
<React.Fragment>
{error ? <p>An error occurred: {String(error)}. Please try again.</p> : null}
<AuthMethodSelector />
</React.Fragment>
);
}Always render the error field from useCriiptoVerify. It surfaces both configuration errors (e.g. invalid domain or clientID, or CORS) raised when the provider mounts, and runtime errors raised during a login attempt (e.g. user cancellation, or OAuth2 errors from the identity provider (IdP)). Without rendering error, misconfiguration and failed logins will appear silent to the user.
Select eIDs programmatically
To control eID methods from your code instead of the dashboard, pass acrValues to AuthMethodSelector:
<AuthMethodSelector
acrValues={['urn:grn:authn:dk:mitid:substantial', 'urn:grn:authn:dk:mitid:high']}
/>See the Authorize URL Builder or individual eID pages for the full list of supported acr_values.
Configure the request per eID
login_hint and scope values are eID specific, so a single provider-level setting rarely fits every button. Pass a beforeAuthorize function to CriiptoVerifyProvider to adjust the request for the eID the user actually picked:
<CriiptoVerifyProvider
domain="{YOUR_IDURA_DOMAIN}"
clientID="{YOUR_IDURA_APPLICATION_CLIENT_ID}"
beforeAuthorize={({ acrValues }) => {
if (acrValues[0].startsWith('urn:grn:authn:dk:mitid')) {
return { scope: 'openid address' };
}
if (acrValues[0].startsWith('urn:grn:authn:se:bankid')) {
return { loginHint: 'stepUp:mrtd' };
}
}}
>
<App />
</CriiptoVerifyProvider>beforeAuthorize runs just before every authorize request is built, whichever way the login was started: AuthMethodSelector, AuthMethodButton, SEBankIDQRCode, loginWithRedirect or loginWithPopup. Return the values you want to change for that one request, or nothing at all to leave it as configured on the provider.
acrValuesis always an array, and holds a single value for logins started from a button orAuthMethodSelectoroptionsholds the request as the SDK would otherwise send it, in case you want to inspect it- you can override
loginHint,scope,prompt,uiLocales,state,nonce,extraUrlParamsand theaction/messageshorthands loginHintis appended to the hints the SDK already adds, so useactionandmessagerather than writingaction:/message:hints yourselfacrValues,redirectUriand the PKCE and response parameters are managed by the SDK and cannot be overridden here. UseredirectUrion the button or selector to change where a single eID returns the user
The hint and scope values differ per eID, see the individual eID pages in the Idura docs for what each one supports.
Send the user directly to an eID login screen
If you don't need the method selector, use loginWithRedirect (or loginWithPopup) and pass a single eID method identifier in acrValues.
// src/App.js
import React from 'react';
import { useCriiptoVerify } from '@criipto/verify-react';
export default function App() {
const { result, loginWithRedirect } = useCriiptoVerify();
if (result?.id_token) {
return <pre>{JSON.stringify(result.id_token, null, 2)}</pre>;
}
return (
<button onClick={() => loginWithRedirect({ acrValues: 'urn:grn:authn:dk:mitid:substantial' })}>
Log in with MitID
</button>
);
}CORS
The SDK makes fetch requests to Idura for two reasons:
- To load application configuration when the provider mounts.
- To push the authorization request (PAR) when a user clicks a login button.
Make sure the origin your React app runs on is included in the list of redirect URLs for your Idura application. Otherwise, both calls will fail with CORS errors.
Sessions
If you want to use the SDK for session management (rather than one-off authentication), you can configure a sessionStore:
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { CriiptoVerifyProvider } from '@criipto/verify-react';
import App from './App';
ReactDOM.render(
<CriiptoVerifyProvider
domain="{YOUR_IDURA_DOMAIN}"
clientID="{YOUR_IDURA_APPLICATION_CLIENT_ID}"
redirectUri={window.location.href}
sessionStore={window.sessionStorage} // or window.localStorage
>
<App />
</CriiptoVerifyProvider>,
document.getElementById('root'),
);When a sessionStore is configured, the SDK stores the id_token in your chosen storage (sessionStorage or localStorage) and invalidates it once it expires.
The SDK will also attempt to retrieve the token on page load via SSO. (This requires SSO enabled on your Idura domain: check Domains → your domain → SSO section in the dashboard).
For longer sessions, you can increase the Token lifetime setting of your Idura application (Applications → your app → Advanced Options).
// src/App.js
import React from 'react';
import { useCriiptoVerify, AuthMethodSelector, OAuth2Error } from '@criipto/verify-react';
export default function App() {
const { claims, error, isLoading } = useCriiptoVerify();
if (isLoading) {
return <div>Loading</div>;
}
if (claims) {
return <pre>{JSON.stringify(claims, null, 2)}</pre>;
}
return (
<React.Fragment>
{error ? (
<p>
An error occurred:{' '}
{error instanceof OAuth2Error
? `${error.error} (${error.error_description})`
: String(error)}
. Please try again.
</p>
) : null}
<AuthMethodSelector />
</React.Fragment>
);
}Logging out
The logout method clears the session store and ends any existing SSO session.
// src/App.js
import React from 'react';
import { useCriiptoVerify, AuthMethodSelector } from '@criipto/verify-react';
import '@criipto/verify-react/index.css';
export default function App() {
const { claims, logout } = useCriiptoVerify();
if (claims) {
return (
<React.Fragment>
<pre>{JSON.stringify(claims, null, 2)}</pre>
<button onClick={() => logout({ redirectUri: window.location.href })}>Log out</button>
</React.Fragment>
);
}
return <AuthMethodSelector />;
}logout takes an optional redirectUri (where to send the user afterwards) and state (an opaque string used to mitigate CSRF attacks, see state).
useEffect + loginWithRedirect
If you are triggering loginWithRedirect inside a useEffect hook, you need to allow the SDK time to initialize a few values before you redirect the user:
const { isLoading, isInitializing, loginWithRedirect } = useCriiptoVerify();
useEffect(() => {
if (isLoading || isInitializing) return;
loginWithRedirect();
}, [isLoading, isInitializing]);Idura
Learn more about Idura and sign up for a free developer account at idura.eu.
Why the package is named @criipto/verify-react
Idura was previously called Criipto, and most of our SDKs keep the @criipto name for backwards compatibility. You can read more about the rebrand in our blog.
