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). |
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 calls onUnauthorized and returns fallback (omitted renders nothing). |
RefreshableRouteGuard | Requires tokenManager. Refreshes when isRefreshNeeded and isRefreshable; authenticated children win, otherwise refreshing node or fallback. Default refreshing text is Refreshing.... |
RouteGuard.onUnauthorized runs during render and can run repeatedly; it is not an effect-based navigation callback. Avoid setting unrelated React state or sending requests from it. 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:150
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:66
RouteGuardProps
export interface RouteGuardProps {
children: ReactNode;
fallback?: ReactNode;
onUnauthorized?: () => void;
}packages/react/src/cosec/RouteGuard.tsx:20
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 · Wow query hooks · Monitoring, refs and fullscreen
