Skip to content

Repository files navigation

AuthKit React

Add authentication to your React app with WorkOS AuthKit. Handles sign-in, sign-up, token refresh, and session management via a hosted OAuth flow.

Installation

npm install @workos-inc/authkit-react

Quick Start

1. Configure the WorkOS Dashboard

  • Add a Redirect URI (e.g. http://localhost:5173) on the Redirects page. This is where WorkOS sends users after they authenticate.
  • Add your app's origin (e.g. http://localhost:5173) to the allowed origins list on the Authentication page of the WorkOS Dashboard.

2. Wrap your app in AuthKitProvider

import{AuthKitProvider}from"@workos-inc/authkit-react";import{createRoot}from"react-dom/client";createRoot(document.getElementById("root")).render(<AuthKitProviderclientId="client_01ABC123DEF456"><App/></AuthKitProvider>,);

3. Add a /login route

Some authentication flows are initiated outside your app — for example, when an admin impersonates a user from the WorkOS Dashboard, or when a third-party triggers login via your app's Sign-in URL. These flows redirect the user to a well-known login path in your app, which must then start the OAuth flow.

Register a /login URL (e.g. http://localhost:5173/login) as the Sign-in URL on the same Redirects page, then handle it in your app:

import{useAuth}from"@workos-inc/authkit-react";import{useEffect}from"react";functionLoginRoute(){const{ signIn }=useAuth();useEffect(()=>{signIn();},[signIn]);return<div>Redirecting...</div>;}

In a router-based app this would be a dedicated route component. In a simple app you can handle it inline:

functionApp(){const{ isLoading, user, signIn }=useAuth();useEffect(()=>{if(window.location.pathname==="/login"){signIn();}},[signIn]);// ... rest of your app}

4. Use the useAuth hook

import{useAuth}from"@workos-inc/authkit-react";functionApp(){const{ isLoading, user, signIn, signUp, signOut, getAccessToken }=useAuth();if(isLoading)return<div>Loading...</div>;if(!user){return(<div><buttononClick={()=>signIn()}>Sign In</button><buttononClick={()=>signUp()}>Sign Up</button></div>);}return(<div><p>Hello, {user.firstName??user.email}</p><buttononClick={()=>signOut()}>Sign Out</button></div>);}

That's it — you have a fully authenticated React app.

API Reference

<AuthKitProvider />

Wrap your app in this component to provide authentication context.

PropTypeRequiredDescription
clientIdstringYesYour WorkOS Client ID (starts with client_)
apiHostnamestringNoYour custom Authentication API domain. Defaults to api.workos.com. In production, this should be set to a domain you own (e.g. auth.example.com)
devModebooleanNoStores tokens in localStorage. Auto-enabled on localhost and 127.0.0.1.
onRedirectCallback(params) => voidNoCalled after a successful authentication. Use to restore app state or navigate.
onRefresh(response) => voidNoCalled when the access token is refreshed.
onRefreshFailure({ signIn }) => voidNoCalled when token refresh fails. Receives signIn to trigger re-authentication.
onBeforeAutoRefresh() => booleanNoCalled before automatic refresh. Return false to skip.
refreshBufferIntervalnumberNoSeconds before token expiration to trigger refresh.

useAuth()

Returns the current auth state and helper methods. Must be called inside <AuthKitProvider>.

State

PropertyTypeDescription
isLoadingbooleantrue during initial authentication check
userUser | nullThe authenticated user, or null
organizationIdstring | nullThe user's current organization
rolestring | nullThe user's role in the current organization
rolesstring[] | nullAll roles for the user in the current organization
permissionsstring[]Permissions for the user's role
featureFlagsstring[]Feature flags enabled for the organization
impersonatorImpersonator | nullSet when an admin is impersonating this user
authenticationMethodAuthenticationMethod | nullHow the user authenticated (e.g. "GoogleOAuth", "SSO")

Methods

MethodSignatureDescription
signIn(opts?) => Promise<void>Redirect to the AuthKit sign-in page
signUp(opts?) => Promise<void>Redirect to the AuthKit sign-up page
signOut(opts?) => voidEnd the session and sign the user out
getAccessToken(opts?) => Promise<string>Get a valid access token, refreshing if needed
getUser() => User | nullSynchronously get the current user
switchToOrganization({ organizationId, signInOpts? }) => Promise<void>Switch to a different organization
getSignInUrl(opts?) => Promise<string>Get the sign-in URL without redirecting
getSignUpUrl(opts?) => Promise<string>Get the sign-up URL without redirecting

signIn / signUp Options

{state?: any;// Data to persist through the auth flow
organizationId?: string;// Pre-select an organization
loginHint?: string;// Pre-fill the email field
invitationToken?: string;// Accept an invitation during sign-up
screenHint?: "sign-in"|"sign-up";// Which screen to show}

signOut Options

{returnTo?: string;// URL to navigate to after sign-out}

User

interfaceUser{id: string;email: string;emailVerified: boolean;profilePictureUrl: string|null;firstName: string|null;lastName: string|null;createdAt: string;updatedAt: string;lastSignInAt: string|null;externalId: string|undefined;}

getClaims(accessToken)

Decodes a JWT access token and returns its claims.

import{getClaims}from"@workos-inc/authkit-react";consttoken=awaitgetAccessToken();constclaims=getClaims(token);// claims.sub, claims.org_id, claims.role, claims.permissions, etc.

Error Classes

  • AuthKitError — Base error class for AuthKit errors.
  • LoginRequiredError — Thrown by getAccessToken() when no user is authenticated.

Recipes

Making Authenticated API Calls

functionDashboard(){const{ getAccessToken }=useAuth();asyncfunctionfetchData(){consttoken=awaitgetAccessToken();constres=awaitfetch("/api/data",{headers: {Authorization: `Bearer ${token}`},});returnres.json();}// ...}

Passing Data Through Auth Flows

Use state to preserve data across the authentication redirect:

// Pass state when starting sign-in<buttononClick={()=>signIn({state: {returnTo: "/dashboard"}})}>
Sign In
</button>

Security:state round-trips through the OAuth redirect as plaintext in the URL and is not integrity protected — treat anything read from it as untrusted input. Before navigating to a returnTo-style value, validate it against your own origin so an attacker cannot smuggle a javascript: URI or an off-site open-redirect target.

// Retrieve it in onRedirectCallback<AuthKitProviderclientId="client_01ABC123DEF456"onRedirectCallback={({ state })=>{if(typeofstate?.returnTo!=="string")return;leturl;try{url=newURL(state.returnTo,window.location.origin);}catch{return;// malformed URL — ignore}// Only navigate to a same-origin destination. Use the parsed absolute// URL, not a value rebuilt from url.pathname (a "//evil.com" pathname// would redirect off-site).if(url.origin===window.location.origin){window.location.href=url.href;}}}><App/></AuthKitProvider>

Handling Token Refresh Failures

<AuthKitProviderclientId="client_01ABC123DEF456"onRefreshFailure={({ signIn })=>{// Session expired — prompt re-authenticationsignIn();}}><App/></AuthKitProvider>

Multi-Organization Switching

functionOrgSwitcher({ organizations }){const{ switchToOrganization, organizationId }=useAuth();return(<selectvalue={organizationId??""}onChange={(e)=>switchToOrganization({organizationId: e.target.value})}>{organizations.map((org)=>(<optionkey={org.id}value={org.id}>{org.name}</option>))}</select>);}

Role-Based UI

functionAdminPanel(){const{ role, permissions }=useAuth();if(role!=="admin")returnnull;return(<div><h2>Admin Panel</h2>{permissions.includes("users:manage")&&<UserManagement/>}</div>);}

About

React SDK for AuthKit

Topics

Resources

Stars

47 stars

Watchers

5 watching

Forks

Releases

Packages

Used by

Contributors

Languages