🔐 Authentication Utilities
The Nodeblocks SDK provides comprehensive authentication utilities for token management, validation, and security. These utilities handle bearer tokens, cookie-based authentication, and various token types for different use cases.
🎯 Overview
Authentication utilities provide secure token generation, validation, and management for both user and application authentication. They support multiple token types and security validation mechanisms.
For service-level configuration (authMode, checkIp, token sign options), see Authentication Service.
Key Features
- Multiple Token Types: User access, app access, refresh, and one-time tokens
- Security Validation: Fingerprint, IP, and user agent validation
- Flexible Authentication: Bearer token and cookie-based authentication
- Two-Layer Tokens: AES-256-CBC encryption envelope around a signed JWT
Token Format
Tokens use a two-layer format:
- Inner layer: A standard JWT signed with
authSignSecret(viajsonwebtoken) - Outer layer: AES-256-CBC encryption with a SHA-256-derived key from
authEncSecret, stored asiv_hex:ciphertext_hex
Use encrypt / decrypt for the envelope and decryptAndVerifyJWT to decrypt and verify in one step.
Default Token Lifetimes
| Token | Default expiresIn |
|---|---|
| User access | '15m' |
| Refresh | '2d' |
| One-time | '5m' |
| App access | none (no default expiry in sign options) |
🔑 Token Generation
generateUserAccessToken
Creates encrypted user access tokens with security validation metadata.
import { utils } from '@nodeblocks/backend-sdk';
const { generateUserAccessToken } = utils;
const token = generateUserAccessToken(
authSecrets,
{ expiresIn: '30m' }, // optional; default '15m'
identityId,
{
fingerprint: 'device-fingerprint',
ip: '192.168.1.1',
domain: 'example.com',
userAgent: 'Mozilla/5.0...'
}
);
Parameters:
authSecrets: Authentication secrets for encryption/signingjwtSignOptions: RequiredSignOptions | undefinedparameter fromjsonwebtoken; passundefinedto use the defaultexpiresIn: '15m'identityId: Identity identifiertokenVerification: Security context for validation
Notes:
- Generated tokens always have
stateful: false(not configurable via this function)
generateAppAccessToken
Creates encrypted app access tokens for service-to-service communication.
import { utils } from '@nodeblocks/backend-sdk';
const { generateAppAccessToken } = utils;
const token = generateAppAccessToken(authSecrets, 'app-service-id');
Parameters:
authSecrets: Authentication secretsappId: Application identifier
generateRefreshToken
Creates encrypted refresh tokens for session management.
import { utils } from '@nodeblocks/backend-sdk';
const { generateRefreshToken } = utils;
const token = generateRefreshToken(
authSecrets,
'jwt-token-id',
identityId,
{
fingerprint: 'device-fingerprint',
ip: '192.168.1.1',
domain: 'example.com',
userAgent: 'Mozilla/5.0...'
},
{ expiresIn: '7d' } // optional; default '2d'
);
Parameters:
authSecrets: Authentication secretsjti: JWT token ID for stateful refresh token trackingidentityId: Identity identifiertokenVerification: Security context for validationjwtSignOptions: OptionalSignOptions(defaultexpiresIn: '2d')
Notes:
- Generated tokens always have
stateful: true(hardcoded, not configurable via this function)
generateOnetimeToken
Creates one-time tokens for temporary access.
import { utils } from '@nodeblocks/backend-sdk';
const { generateOnetimeToken } = utils;
const token = generateOnetimeToken(
authSecrets,
{ identityId: 'id-123', action: 'password-reset' },
{
fingerprint: 'device-fingerprint',
ip: '192.168.1.1',
domain: 'example.com',
userAgent: 'Mozilla/5.0...'
},
{ expiresIn: '1h' } // optional; default '5m'
);
Parameters:
authSecrets: Authentication secretsdata: Payload to embed in the token (Record<string, unknown>)tokenVerification: Security context for validationjwtSignOptions: OptionalSignOptions(defaultexpiresIn: '5m')
Notes:
- Generated tokens always have
stateful: true(hardcoded, not configurable via this function)
🔍 Token Validation
getBearerTokenInfo
Extracts token information from request authorization header. Default authentication function for bearer tokens.
import { utils } from '@nodeblocks/backend-sdk';
const { getBearerTokenInfo } = utils;
const tokenInfo = await getBearerTokenInfo(payload);
Process:
- Extracts token from
Authorization: Bearer <token>header - Decrypts and verifies JWT signature
- Validates token type (user or app)
- Performs security checks for user tokens (app tokens skip security checks)
- Returns token information
IP binding: Controlled by payload.context.configuration.checkIp. When unset, IP checks default to enabled (checkIp ?? true).
Errors: Throws NodeblocksError(401) when the token is missing, invalid, not an access token, or fails security checks (user tokens). App access tokens skip security checks and return AppAccessTokenInfo.
getCookieTokenInfo
Extracts token information from cookies. Authentication function for cookie-based tokens when authMode is 'cookie'.
import { utils } from '@nodeblocks/backend-sdk';
const { getCookieTokenInfo } = utils;
const tokenInfo = await getCookieTokenInfo(payload);
Use cases:
- Web applications with cookie-based authentication (
cookies.accessToken) - Server-side session management with
cookie-parser
Note: Cookie mode differs from bearer mode by token transport only. Security checks (fingerprint, IP, user agent) use the same logic as getBearerTokenInfo, including configuration.checkIp ?? true.
Errors: Throws NodeblocksError(401) when cookies.accessToken is missing, invalid, not an access token, or fails security checks (user tokens). App access tokens skip security checks and return AppAccessTokenInfo.
defaultRefreshTokenBodyAuth
Default authentication function for refresh tokens fetched from the request body. It always extracts the token; when decryptToken is true, it decrypts, validates, and performs security checks.
import { utils } from '@nodeblocks/backend-sdk';
const { defaultRefreshTokenBodyAuth } = utils;
const { token, tokenInfo } = await defaultRefreshTokenBodyAuth(
authSecrets,
request,
true, // decryptToken
logger
);
Parameters:
authSecrets: Authentication secrets for token decryptionrequest: HTTP request object containing the refresh tokendecryptToken: Whether to decrypt and validate the token (default: false)logger: Optional logger for security check logging
Process:
- Extracts refresh token from
request.body.refreshToken - Retrieves token verification context (fingerprint, IP, user agent)
- Validates token format and presence
- Decrypts and verifies JWT signature (if
decryptTokenis true) - Validates token type is refresh token
- Performs security checks with IP validation enabled
- Returns token and token information
defaultRefreshTokenCookieAuth
Default authentication function for refresh tokens fetched from cookies. It always extracts the token; when decryptToken is true, it decrypts, validates, and performs security checks. In that mode it returns both token and tokenInfo.
import { utils } from '@nodeblocks/backend-sdk';
const { defaultRefreshTokenCookieAuth } = utils;
const { token, tokenInfo } = await defaultRefreshTokenCookieAuth(
authSecrets,
request,
true, // decryptToken
logger
);
Parameters:
authSecrets: Authentication secrets for token decryptionrequest: HTTP request object containing the refresh token in cookiesdecryptToken: Whether to decrypt and validate the token (default: false)logger: Optional logger for security check logging
Process:
- Extracts refresh token from
request.cookies.refreshToken - Retrieves token verification context (fingerprint, IP, user agent)
- Validates token format and presence
- Decrypts and verifies JWT signature (if
decryptTokenis true) - Validates token type is refresh token
- Performs security checks with IP validation enabled (
checkIp: true) - Returns token and token information (when
decryptTokenis true)
Key Differences from Body Auth:
- Source: Reads from cookies instead of request body
resolveRefreshTokenFromRequest
Resolves a refresh token from cookie and/or request body. When both sources are present, they must refer to the same token.
import { utils } from '@nodeblocks/backend-sdk';
const { resolveRefreshTokenFromRequest } = utils;
const result = await resolveRefreshTokenFromRequest(authSecrets, request, logger);
if (result.isOk() && result.value) {
const { token, tokenInfo } = result.value;
}
Parameters:
authSecrets: Authentication secrets for token decryptionrequest: HTTP request objectlogger: Optional logger for security check logging
Returns:
Result<{ token: string; tokenInfo: RefreshTokenInfo } | undefined, NodeblocksError>- Returns
ok(undefined)when no valid refresh token is found - Returns
err(...)with 401 when cookie and body tokens do not match
🛡️ Security Functions
tokenPassesSecurityCheck
Validates token security context.
import { utils } from '@nodeblocks/backend-sdk';
const { tokenPassesSecurityCheck } = utils;
const isValid = tokenPassesSecurityCheck(
tokenInfo,
{
fingerprint: 'device-fingerprint',
ip: '192.168.1.1',
userAgent: 'Mozilla/5.0...'
},
logger,
{ checkIp: true }
);
Validation logic:
- Fingerprint must match — if it does not, the check fails immediately
- If
checkIpis disabled, the check passes (fingerprint already matched) - If
checkIpis enabled and IP matches, the check passes - If
checkIpis enabled and IP does not match, the check passes only when user agent matches; otherwise it fails
Parameters:
tokenInfo: User access or refresh token infotokenVerification: Current request context (domain,fingerprint,ip,userAgent)logger: Optional loggeroptions.checkIp: Whether to perform IP binding checks (default:true)
decryptAndVerifyJWT
Decrypts the AES envelope and verifies the inner JWT signature.
import { utils } from '@nodeblocks/backend-sdk';
const { decryptAndVerifyJWT } = utils;
const tokenInfo = decryptAndVerifyJWT(authSecrets, encryptedToken);
Errors: Throws NodeblocksError with status 401 when the token is empty, malformed, invalid, or expired. Does not perform fingerprint/IP/user-agent checks — callers (e.g. authenticators) must run tokenPassesSecurityCheck separately for user tokens.
🔧 Helper Functions
getBearerToken
Extracts bearer token from request headers.
import { utils } from '@nodeblocks/backend-sdk';
const { getBearerToken } = utils;
const token = getBearerToken(request.headers);
// Returns: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
Errors: Returns undefined when the Authorization header is absent. Throws NodeblocksError with status 422 when the header is present but not a string or not in Bearer <token> format.
getFingerprint
Extracts device fingerprint from headers.
import { utils } from '@nodeblocks/backend-sdk';
const { getFingerprint } = utils;
const fingerprint = getFingerprint(request.headers, 'x-nb-fingerprint');
Errors: Throws NodeblocksError with status 422 when the header is present but not a string.
getUserAgent
Extracts user agent from request headers.
import { utils } from '@nodeblocks/backend-sdk';
const { getUserAgent } = utils;
const userAgent = getUserAgent(request.headers);
getRequestInfo
Extracts request metadata for token validation.
import { utils } from '@nodeblocks/backend-sdk';
const { getRequestInfo } = utils;
const requestInfo = getRequestInfo(request);
// Returns: { host, ip, method, path, url }
getExpiresIn
Normalizes token expiration time values. Converts various input formats to a standardized expiration time format.
import { utils } from '@nodeblocks/backend-sdk';
const { getExpiresIn } = utils;
const expiresIn = getExpiresIn('24h'); // Returns: '24h'
const expiresIn2 = getExpiresIn(3600000); // Returns: 3600000
const expiresIn3 = getExpiresIn(); // Returns: '48h' (default)
Parameters:
expirationTime: Optional expiration time as string or number
Returns:
number | string: Normalized expiration time (default: '48h')
Behavior:
- If
expirationTimeisnullorundefined: returns default '48h' - If
expirationTimeis a valid number: returns the number - If
expirationTimeis a non-numeric string: returns the string as-is - If
expirationTimeis a numeric string: converts it to a number
getExpirationDate
Calculates the absolute expiration date based on a duration string or milliseconds.
import { utils } from '@nodeblocks/backend-sdk';
const { getExpirationDate } = utils;
const expirationDate = getExpirationDate('7d'); // Returns: Date object 7 days from now
const expirationDate2 = getExpirationDate(3600000); // Returns: Date object 1 hour from now
const expirationDate3 = getExpirationDate(); // Returns: Date object 2 days from now (default)
Parameters:
expiresIn: Duration string (e.g., '7d', '24h', '30m') or milliseconds (default:'2d')
Returns:
Date: Absolute expiration date and time
Supported Duration Formats:
'7d'- 7 days'24h'- 24 hours'30m'- 30 minutes'60s'- 60 seconds- Numeric values in milliseconds
deriveCookieMaxAge
Converts a token's expiresIn value into milliseconds for Express cookie maxAge options.
import { utils } from '@nodeblocks/backend-sdk';
const { deriveCookieMaxAge } = utils;
const maxAge = deriveCookieMaxAge('15m'); // Returns: 900000 (ms)
const maxAge2 = deriveCookieMaxAge(3600); // Returns: 3600000 (3600 seconds → ms)
Parameters:
expiresIn: Duration string (parsed viams()) or a numeric value in seconds (matchingjsonwebtokenconvention)
Returns:
number: Duration in milliseconds
Note: Unlike getExpirationDate, bare numeric values here are treated as seconds, not milliseconds.
isAccessToken
Checks if a token is an access token (user or app) and can be used as a simple type guard.
import { utils } from '@nodeblocks/backend-sdk';
const { isAccessToken } = utils;
if (isAccessToken(tokenInfo)) {
// tokenInfo is AccessTokenInfo (accessType: 'user' | 'app')
}
Parameters:
tokenInfo: Token information object to check
Returns:
boolean:trueif the token is an access token, otherwisefalse
isUserAccessToken
Checks if a token is specifically a user access token.
import { utils } from '@nodeblocks/backend-sdk';
const { isUserAccessToken } = utils;
if (isUserAccessToken(tokenInfo)) {
// tokenInfo is UserAccessTokenInfo
console.log(tokenInfo.identityId);
}
Parameters:
tokenInfo: Token information object to check
Returns:
boolean:trueif the token is a user access token, otherwisefalse
isAppAccessToken
Checks if a token is specifically an app access token.
import { utils } from '@nodeblocks/backend-sdk';
const { isAppAccessToken } = utils;
if (isAppAccessToken(tokenInfo)) {
// tokenInfo is AppAccessTokenInfo
console.log(tokenInfo.appId);
}
Parameters:
tokenInfo: Token information object to check
Returns:
boolean:trueif the token is an app access token, otherwisefalse
isRefreshToken
Checks if a token is a refresh token.
import { utils } from '@nodeblocks/backend-sdk';
const { isRefreshToken } = utils;
if (isRefreshToken(tokenInfo)) {
// tokenInfo is RefreshTokenInfo
console.log(tokenInfo.jti);
}
Parameters:
tokenInfo: Token information object to check
Returns:
boolean:trueif the token is a refresh token, otherwisefalse
isOnetimeToken
Checks if a token is a one-time token.
import { utils } from '@nodeblocks/backend-sdk';
const { isOnetimeToken } = utils;
if (isOnetimeToken(tokenInfo)) {
// tokenInfo is OnetimeTokenInfo
console.log(tokenInfo.data);
}
Parameters:
tokenInfo: Token information object to check
Returns:
boolean:trueif the token is a one-time token, otherwisefalse
isValidAppAccessToken
Checks that an app access token has an appId present.
import { utils } from '@nodeblocks/backend-sdk';
const { isValidAppAccessToken } = utils;
if (isValidAppAccessToken(tokenInfo)) {
// tokenInfo is AppAccessTokenInfo with appId present
}
Parameters:
tokenInfo: Token information object to check
Returns:
boolean:trueif token is an app access token withappIdpresent, otherwisefalse
isValidUserAccessToken
Checks that a user access token has an identityId present.
import { utils } from '@nodeblocks/backend-sdk';
const { isValidUserAccessToken } = utils;
if (isValidUserAccessToken(tokenInfo)) {
// tokenInfo is UserAccessTokenInfo with identityId present
}
Parameters:
tokenInfo: Token information object to check
Returns:
boolean:trueif token is a user access token withidentityIdpresent, otherwisefalse
retrieveTokenVerification
Create token verification metadata from an Express Request.
import { utils } from '@nodeblocks/backend-sdk';
const { retrieveTokenVerification } = utils;
const verification = retrieveTokenVerification(request);
// { domain, fingerprint, ip, userAgent }
validateAuthSecrets
Validate required auth secrets and throw if missing or too short.
import { utils } from '@nodeblocks/backend-sdk';
const { validateAuthSecrets } = utils;
validateAuthSecrets(authSecrets); // throws on invalid configuration
validateAuthSecrets(authSecrets, 24); // optional minimum length (default: 18)
Errors: Throws NodeblocksError with status 500 when secrets are missing or shorter than the minimum length.
generateMailBody
Interpolate a URL and options into an email template.
import { utils } from '@nodeblocks/backend-sdk';
const { generateMailBody } = utils;
const body = generateMailBody(
'Click here: ${url}',
'https://example.com/reset?token=${token}',
{ token: 'abc' }
);
authSecretsValidationErrorMessage
Return a human-readable error for invalid auth secrets (temporary helper).
import { utils } from '@nodeblocks/backend-sdk';
const { authSecretsValidationErrorMessage } = utils;
const msg = authSecretsValidationErrorMessage(authSecrets);
if (msg) throw new Error(msg);
// Optional minimum length (default: 18)
const msg2 = authSecretsValidationErrorMessage(authSecrets, 24);
🔐 Encryption Functions
encrypt
Encrypts a string using AES-256-CBC. Returns iv_hex:ciphertext_hex.
import { utils } from '@nodeblocks/backend-sdk';
const { encrypt } = utils;
const encrypted = encrypt(authSecrets.authEncSecret, 'sensitive-data');
decrypt
Decrypts an AES-256-CBC envelope (iv_hex:ciphertext_hex).
import { utils } from '@nodeblocks/backend-sdk';
const { decrypt } = utils;
const decrypted = decrypt(authSecrets.authEncSecret, encryptedData);
Errors: Throws NodeblocksError with status 401 when the input is empty, malformed, or invalid.
🔑 Password Functions
hash
Hashes passwords using bcrypt with cost factor 10.
import { utils } from '@nodeblocks/backend-sdk';
const { hash } = utils;
const hashedPassword = await hash('user-password');
Implementation: Uses bcrypt with 10 salt rounds (bcryptHash(s, 10)).
compareHash
Compares password with hash.
import { utils } from '@nodeblocks/backend-sdk';
const { compareHash } = utils;
const isValid = await compareHash('user-password', hashedPassword);
📊 Token Types
Token interfaces are exported from the types namespace (source: src/types/authentication.ts), not from utils:
import { types } from '@nodeblocks/backend-sdk';
type UserAccessTokenInfo = types.UserAccessTokenInfo;
type AppAccessTokenInfo = types.AppAccessTokenInfo;
type RefreshTokenInfo = types.RefreshTokenInfo;
type OnetimeTokenInfo = types.OnetimeTokenInfo;
User Access Token
interface UserAccessTokenInfo {
accessType: 'user';
identityId: string;
type: 'access';
stateful: boolean;
fingerprint?: string;
ip?: string;
domain?: string;
target?: string;
userAgent?: string;
}
App Access Token
interface AppAccessTokenInfo {
accessType: 'app';
appId: string;
type: 'access';
}
Refresh Token
interface RefreshTokenInfo {
type: 'refresh';
jti: string;
identityId: string;
stateful: true;
fingerprint?: string;
ip?: string;
domain?: string;
userAgent?: string;
}
One-time Token
interface OnetimeTokenInfo {
type: 'onetime';
data: Record<string, unknown>;
stateful: true;
fingerprint?: string;
ip?: string;
domain?: string;
target?: string;
userAgent?: string;
}