@bookmie/sjwt
v1.0.6
Published
SDK for SJWT Security Platform, wrapping device fingerprinting and JWT revocation operations.
Downloads
776
Maintainers
Readme
SJWT SDK (Node.js / TypeScript)
Secure JWT (SJWT) SDK for Node.js and TypeScript applications. This SDK provides a simple, type-safe interface for generating, verifying, and rotating JWT tokens, with built-in protection against common vulnerabilities like replay attacks and token theft.
Features
- Token Lifecycle Management: Generate, verify, and rotate JWT tokens with ease.
- Security Features:
- Fingerprint Protection: Tokens are tied to a unique fingerprint of the device/browser.
- IP Binding: Tokens are validated against the IP address from which they were issued.
- User-Agent Binding: Tokens are validated against the User-Agent string.
- Revocation: Instant token revocation with real-time statistics.
- Express Middleware: Seamless integration with Express.js applications.
- TypeScript Support: Fully typed with TypeScript interfaces and JSDoc.
Installation
npm install @bookmie/sjwt
# or
yarn add @sbookmie/sjwtConfiguration
You must configure the SDK using environment variables from your dashboard before initiating the client.
| Environment Variable | Description | Default |
|----------------------|-------------|---------|
| SJWT_PROJECT_ID | Your project ID | (Required) |
| SJWT_SIGNATURE_KEY | Your signature key | (Required) |
Usage
1. Initialization
Initialize the SDK by invoking new SJWT(). The constructor automatically triggers an initialization check binding your project context.
import { SJWT } from "@bookmie/sjwt";
// Dependencies loaded from process.env automatically
const sjwt = new SJWT();
2. Generating a Token
Generate a new token with optional payload and TTL. Pass the raw Node/Express incoming request (req), and the SDK will automatically extract network fields and build a secure digital fingerprint.
app.post("/login", async (req, res) => {
const options: SignOptions = {
payload: { userId: "user-123", role: "admin" },
ttlSeconds: 3600, // 1 hour
type: "ACCESS", // ACCESS, REFRESH
req // Pass the Express or Node.js request object directly
};
const tokenResponse = await sjwt.sign(options);
res.json({
token: tokenResponse.token,
tokenType: tokenResponse.tokenType,
expiresIn: tokenResponse.expiresIn
});
});3. Verifying a Token
Verify a token manually by providing the raw request. The SDK extracts IP, User-Agent, and Accept-Language for verification automatically.
app.get("/verify", async (req, res) => {
const result = await sjwt.verify({
token: "your-token",
req // The incoming Express/Node request
});
if (result.valid) {
console.log("Token is valid. Claims:", result.claims);
} else {
console.log("Token is invalid. Error:", result.errorCode);
}
});
if (!result.valid) {
switch (result.errorCode) {
case "DEVICE_MISMATCH": // stolen token
case "ANOMALY": // anomaly flagged
//other anomalies
case "REVOKED": // already revoked
}
}4. Rotating a Refresh Token
Rotate an existing refresh token to generate a new one, optionally with an updated payload and TTL.
app.post("/refresh", async (req, res) => {
const rotatedToken = await sjwt.rotate({
oldToken: "your-old-refresh-token",
payload: { userId: "user-123", role: "admin" },
ttlSeconds: 3600,
req // Pass the incomng request for verification and re-fingerprinting
});
res.json({
token: rotatedToken.token,
tokenType: rotatedToken.tokenType,
expiresIn: rotatedToken.expiresIn
});
});5. Revoking a Token
Revoke a token immediately.
await sjwt.revoke("your-token", "ACCESS");
console.log("Token revoked.");6. Express Middleware
Integrate the verification layer across routes seamlessly with the SJWT Express middleware.
import express from "express";
import { SJWT, sjwtMiddleware } from "@bookmie/sjwt";
const app = express();
const sjwt = new SJWT();
app.use(express.json());
// Apply globally or on select routes
app.use(sjwtMiddleware(sjwt));
// Protected route
app.get("/api/protected", (req, res) => {
// If the request makes it here, verification succeeded.
// req.sjwt is populated by the middleware containing extracted claims.
res.json({ message: "Access granted", claims: req.sjwt?.claims });
});
app.listen(3000, () => console.log("Server running on port 3000"));Error Codes
The verify() method and middleware return structured error codes when a token is invalid.
| Error Code | Description |
|------------|-------------|
| REVOKED | Token has been revoked by the security engine or an admin. |
| DEVICE_MISMATCH | Device fingerprint does not match the one bound to the token. |
| INVALID_TOKEN | Token is malformed, expired, or otherwise unverifiable. |
| REPLAY_ATTACK | Token reuse detected within the replay detection window. |
| ANOMALY | Generic anomaly flagged by the detection engine. |
| ANOMALY_HIGH_REQUEST_FREQUENCY | Unusually high request frequency detected. |
| ANOMALY_IP_HOPPING | Token used from a different IP address than expected. |
| ANOMALY_USER_AGENT_CHANGE | Token used with a different User-Agent than expected. |
| HTTP_<status> | Backend returned an HTTP error (e.g. HTTP_401, HTTP_500). |
| NETWORK_ERROR | Network failure or timeout during verification. |
Handling errors
const result = await sjwt.verify({ token, req });
if (!result.valid) {
switch (result.errorCode) {
case "DEVICE_MISMATCH":
// stolen token or device changed
break;
case "ANOMALY":
case "ANOMALY_HIGH_REQUEST_FREQUENCY":
case "ANOMALY_IP_HOPPING":
case "ANOMALY_USER_AGENT_CHANGE":
// anomaly flagged
break;
case "REPLAY_ATTACK":
// replay detected
break;
case "REVOKED":
// token revoked
break;
case "INVALID_TOKEN":
// malformed or expired
break;
}
}Security Considerations
- Reverse Proxies: The SDK extracts the IP using the standard
X-Forwarded-ForHTTP header, then falls back toreq.socket.remoteAddress. If you are running behind a reverse proxy (Nginx, ALB, Cloudflare, etc.), ensure Express is configured to trust the proxy (e.g.app.set('trust proxy', true)). - Fingerprint: The SDK computes a deterministic fingerprint utilizing browser standards sent in headers (
User-AgentandAccept-Language). - Token Rotation: Rotate refresh tokens to avoid a potential compromise.
- Revocation: The global SJWT threat detection handles instant revocation and blocks blacklisted tokens via a centralized cuckoo filter implementation. Use the revoke functionality immediately when a token acts suspiciously or logout.
License
ISC
