Security hooks and route guards
SecurityProvider requires an existing TokenStorage and children, then makes useSecurity state available through context. Token creation/refresh belongs to CoSec; a route guard only decides which React node to render and is not a server authorization boundary.
| API | Contract |
|---|---|
useSecurity(tokenStorage, options = {}) | Returns currentUser, authenticated, signIn, signOut; missing token uses ANONYMOUS_USER (sub anonymous, empty jti, zero iat/exp). authenticated (access token unexpired) is computed at render; the hook re-renders when the refresh token expires, so an idle page signs out then, while a refreshable session is renewed by the next request. |
signIn(tokenOrAsyncProvider) | Await provider if supplied, store token, invoke onSignIn. Returns Promise<void>; provider/storage/callback failures propagate. |
signOut() | Remove token and invoke onSignOut; synchronous exceptions propagate. |
useSecurityContext() | Returns context; throws outside SecurityProvider. |
RouteGuard | Authenticated: children. Otherwise returns fallback (omitted renders nothing) and calls onUnauthorized after commit. |
RefreshableRouteGuard | Requires tokenManager. Refreshes when isRefreshNeeded and isRefreshable; authenticated children win, otherwise the refreshing node while it refreshes, or fallback when nothing is refreshable or the refresh rejects. Default refreshing text is Refreshing.... |
RouteGuard.onUnauthorized runs in an effect after the render commits, once each time authenticated becomes (or starts out) false, so it can call navigate(); StrictMode in development may run it twice, as it does any effect. The latest callback is used; changing it alone does not call it again. RefreshableRouteGuard logs refresh errors; it does not expose a local error state or cancel the token manager on unmount. The manager and storage remain application-owned. Context updates follow storage subscriptions, not an independent timer that recomputes authentication every second. Switching tokenStorage changes subscription and action targets; callbacks read latest options.
Complete example
import type { TokenStorage } from '@ahoo-wang/fetcher-cosec';
import {
SecurityProvider,
RouteGuard,
useSecurityContext,
} from '@ahoo-wang/fetcher-react';
function Account() {
const { currentUser, signOut } = useSecurityContext();
return <button onClick={signOut}>Sign out {currentUser.sub}</button>;
}
export function SecureApp({ storage }: { storage: TokenStorage }) {
return (
<SecurityProvider tokenStorage={storage}>
<RouteGuard fallback={<p>Please sign in.</p>}>
<Account />
</RouteGuard>
</SecurityProvider>
);
}Public signatures and types
These signatures follow declarations reachable from the current root entry. ? marks optional input; generics/interfaces only constrain compile-time types. Locate inherited and related types through the symbol index. Runtime defaults and failure behavior are described above.
SecurityProvider
export function SecurityProvider(
options: SecurityContextOptions,
): import('react').JSX.Element;packages/react/src/cosec/SecurityContext.tsx:107
useSecurityContext
export function useSecurityContext(): SecurityContextValue;packages/react/src/cosec/SecurityContext.tsx:146
SecurityContextValue
export type SecurityContextValue = UseSecurityReturn;packages/react/src/cosec/SecurityContext.tsx:30
SecurityContext
declare const SecurityContext: import('react').Context<
UseSecurityReturn | undefined
>;packages/react/src/cosec/SecurityContext.tsx:41
SecurityContextOptions
export interface SecurityContextOptions extends UseSecurityOptions {
tokenStorage: TokenStorage;
children: ReactNode;
}packages/react/src/cosec/SecurityContext.tsx:49
useSecurity
export function useSecurity(
tokenStorage: TokenStorage,
options?: UseSecurityOptions,
): UseSecurityReturn;Implementation defaults: options = {}.
packages/react/src/cosec/useSecurity.ts:155
ANONYMOUS_USER
declare const ANONYMOUS_USER: CoSecJwtPayload;packages/react/src/cosec/useSecurity.ts:29
UseSecurityOptions
export interface UseSecurityOptions {
onSignIn?: () => void;
onSignOut?: () => void;
}packages/react/src/cosec/useSecurity.ts:39
UseSecurityReturn
export interface UseSecurityReturn {
currentUser: CoSecJwtPayload;
authenticated: boolean;
signIn: (compositeTokenProvider: CompositeTokenProvider) => Promise<void>;
signOut: () => void;
}packages/react/src/cosec/useSecurity.ts:56
RouteGuard
Expand all fields and members
export function RouteGuard(
options: RouteGuardProps,
):
| string
| number
| bigint
| boolean
| import('react').JSX.Element
| Iterable<ReactNode>
| Promise<
| string
| number
| bigint
| boolean
| import('react').ReactPortal
| import('react').ReactElement<
unknown,
string | import('react').JSXElementConstructor<any>
>
| Iterable<ReactNode>
| null
| undefined
>
| null
| undefined;packages/react/src/cosec/RouteGuard.tsx:69
RouteGuardProps
export interface RouteGuardProps {
children: ReactNode;
fallback?: ReactNode;
onUnauthorized?: () => void;
}packages/react/src/cosec/RouteGuard.tsx:21
RefreshableRouteGuard
export function RefreshableRouteGuard(
options: RefreshableRouteGuardProps,
): import('react').JSX.Element;packages/react/src/cosec/RefreshableRouteGuard.tsx:28
RefreshableRouteGuardProps
export interface RefreshableRouteGuardProps extends Omit<
RouteGuardProps,
'onUnauthorized'
> {
refreshing?: ReactNode;
tokenManager: JwtTokenManager;
}packages/react/src/cosec/RefreshableRouteGuard.tsx:20
Related topics
Fetcher hooks · Promise and query state · API hook factories · Debounced execution · Storage and event subscriptions · Latest and stable values
