This project is designed to handle authentication using OAuth2 with Hydra and OIDC. The project is divided into two phases:
- Phase 1: OAuth2 with Hydra
- Phase 2: OIDC Public Client (coming soon)
- Node.js (>= 14.x)
- npm (>= 6.x)
-
Clone the repository:
git clone https://github.com/your-username/auth-client.git cd auth-client
-
Install dependencies:
npm install
-
Start the development server:
npm run dev
In this phase, we use OAuth2 with Hydra for authentication.
- Follow the Hydra documentation to set up Hydra in QA box environment.
- Configure your OAuth2 settings in the project.
Use the useOAuth2
hook within your components.
import React from 'react';
import { useOAuth2, TOAuth2EnabledAppList } from '@deriv-com/auth-client';
const YourComponent = () => {
const [OAuth2EnabledApps, OAuth2EnabledAppsInitialised] = useGrowthbookGetFeatureValue<TOAuth2EnabledAppList>({
featureFlag: 'hydra_be',
});
const { logout } = useAuthData(); // Your custom hook or function to handle logout
const OAuth2GrowthBookConfig = {
OAuth2EnabledApps,
OAuth2EnabledAppsInitialised
};
const WSLogoutAndRedirect = async () => {
await logout();
// Redirect or perform any additional actions here
};
const { OAuth2Logout } = useOAuth2(OAuth2GrowthBookConfig, WSLogoutAndRedirect);
return (
<div>
<button onClick={OAuth2Logout}>Logout</button>
</div>
);
};
export default YourComponent;
In this phase, we will transition to using an OIDC public client for authentication.
OIDC Login Flow - https://service-auth.deriv.team/resources/rfc/public-client/#login
- The app must first fetch the OpenID configuration /.well-known/openid-configuration to find the authorization_endpoint.
- Get the authorization_endpoint and redirect the user to the authorization_endpoint with the necessary parameters.
- The authorization server will authenticate the user and redirect the user back to the app with one time code.
- Get the token_endpoint from the OpenID configuration and exchange the one time code for an access token and id token.
- Make a POST request with Bearer token received from the token_endpoint to the legacy_endpoint to get the legacy tokens.
- Use the legacy tokens to authenticate the user.
In this phase, you will configure the OIDC endpoints by dynamically fetching the .well-known/openid-configuration from the server. The OIDC configuration file includes essential details like the authorization_endpoint, token_endpoint, and issuer.
You can modify your configuration in the localStorage or retrieve the necessary details dynamically when required.
To initiate the OIDC Authentication flow, you must first call requestOidcAuthentication
, which will redirect the user to the URL specified in redirect_uri
.
import { requestOidcAuthentication } from '@deriv-com/auth-client';
const handleLoginClick = async () => {
const app_id = 'your-app-id'; // The ID of your app
const redirect_uri = 'http://your-app/callback'; // The URL to redirect to after successful login
const postLogoutRedirectUri = 'http://your-app/'; // The URL to redirect to after logging out
await requestOidcAuthentication(app_id, redirect_uri, postLogoutRedirectUri); // If successful, the user will be redirected to the redirectUri
};
Once the app has been redirected to the login page and user has entered their credentials, OIDC will redirect the user back to the redirect_uri
URL that you have specified when calling requestOidcAuthentication
. The redirect URL will have several new query parameters added automatically, which includes code
containing the one-time ORY code in the format of ory_ac...
and the scope which is openid
.
Once the user has been redirected to the page, requestOidcToken
should be called next to retrieve the access tokens.
// RedirectPage.tsx
import { requestOidcToken } from '@deriv-com/auth-client'
const RedirectPage = () => {
const fetchToken = async () => {
const app_id = 'your-app-id'; // The ID of your app
const redirect_uri = 'http://your-app/callback'; // The URL to redirect to after successful login
const postLogoutRedirectUri = 'http://your-app/'; // The URL to redirect to after logging out
const { accessToken } = await requestOidcToken(app_id, redirect_uri, postLogoutRedirectUri)
}
useEffect(() => {
fetchToken()
}, [])
}
For the last step, when the access token has been fetched, you will need to call requestLegacyToken
with the access token passed-in to get the tokens needed to be passed into the authorize
endpoint.
// RedirectPage.tsx
import { requestOidcToken, requestLegacyToken } from '@deriv-com/auth-client'
const RedirectPage = () => {
const fetchToken = async () => {
const app_id = 'your-app-id'; // The ID of your app
const redirect_uri = 'http://your-app/callback'; // The URL to redirect to after successful login
const postLogoutRedirectUri = 'http://your-app/'; // The URL to redirect to after logging out
const { accessToken } = await requestOidcToken(app_id, redirect_uri, postLogoutRedirectUri)
// Once the access token is returned from `requestOidcToken` and is available, call `requestLegacyToken` to finally retrieve the tokens to pass into authorize
const tokens = await requestLegacyToken(accessToken);
// You can pass one of the tokens to authorize to login the user
callAuthorize(tokens.token1)
}
useEffect(() => {
fetchToken()
}, [])
}