auth: Bearer-before-cookie token extraction; JWT_CLOCK_TOLERANCE for clock skew
extractToken now checks Authorization: Bearer before the accessToken cookie so injected headers (Electron, API clients) cannot be shadowed by stale cookies. JWT_CLOCK_TOLERANCE env var (seconds) is passed to jwt.verify as clockTolerance when non-zero — set in .env for local dev to absorb clock skew vs production. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
0b06c252a3
commit
cb2fba6e8b
|
|
@ -19,15 +19,16 @@ const JWT_SECRET = process.env.JWT_SECRET ?? '';
|
|||
const AUTH_HOST = process.env.AUTH_HOST ?? 'https://account.rokojori.com';
|
||||
const AUTH_INTERNAL_HOST = process.env.AUTH_INTERNAL_HOST ?? AUTH_HOST;
|
||||
const COOKIE_DOMAIN = process.env.COOKIE_DOMAIN ?? '.rokojori.com';
|
||||
const CLOCK_TOLERANCE = parseInt( process.env.JWT_CLOCK_TOLERANCE ?? '0', 10 );
|
||||
|
||||
// ── Internal helpers ───────────────────────────────────────────────────────────
|
||||
|
||||
function extractToken( req: Request ): string | undefined
|
||||
{
|
||||
const cookie = req.cookies?.accessToken as string | undefined;
|
||||
if ( cookie ) return cookie;
|
||||
const header = req.headers.authorization;
|
||||
if ( header?.startsWith( 'Bearer ' ) ) return header.slice( 7 );
|
||||
const cookie = req.cookies?.accessToken as string | undefined;
|
||||
if ( cookie ) return cookie;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
|
@ -100,7 +101,7 @@ export function jwtMiddleware( req: Request, res: Response, next: NextFunction )
|
|||
|
||||
try
|
||||
{
|
||||
req.auth = jwt.verify( token, JWT_SECRET ) as AuthPayload;
|
||||
req.auth = jwt.verify( token, JWT_SECRET, CLOCK_TOLERANCE ? { clockTolerance: CLOCK_TOLERANCE } : {} ) as AuthPayload;
|
||||
req.rawToken = token;
|
||||
next();
|
||||
return;
|
||||
|
|
|
|||
Loading…
Reference in New Issue