JWT Tokens
The Auth wire uses JSON Web Tokens (JWT) for stateless authentication. Tokens are signed using HMAC-SHA256 by default.
Configuration
auth({
jwt: {
secret: process.env.JWT_SECRET, // Required
expiresIn: "7d", // Token lifetime
issuer: "my-app", // Token issuer claim
audience: "my-app-users", // Token audience claim
refreshToken: {
enabled: true, // Enable refresh tokens
expiresIn: "30d", // Refresh token lifetime
},
},
});
Generating Tokens
// Generate a token for a user
const token = app.auth.generateToken({
userId: user._id,
email: user.email,
role: "admin",
});
// => "eyJhbGciOiJIUzI1NiIs..."
// Generate with custom expiration
const shortToken = app.auth.generateToken(
{ userId: user._id },
{ expiresIn: "1h" }
);
Verifying Tokens
try {
const payload = app.auth.verifyToken(token);
console.log(payload.userId); // "65a1b2c3..."
console.log(payload.email); // "alice@example.com"
console.log(payload.exp); // 1737000000
} catch (err) {
// Token is invalid or expired
}
Using Tokens in REST API
Include the token in the Authorization header:
curl http://localhost:3000/auth/me \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
Response (200):
{
"user": {
"_id": "65a1b2c3d4e5f6a7b8c9d0e1",
"email": "alice@example.com",
"name": "Alice Johnson"
}
}
Response (401):
{
"error": {
"code": "INVALID_TOKEN",
"message": "Token is expired or invalid"
}
}
Refresh Tokens
When refresh tokens are enabled, the login response includes both an access token and a refresh token:
curl -X POST http://localhost:3000/auth/login \
-H "Content-Type: application/json" \
-d '{"email": "alice@example.com", "password": "password"}'
{
"user": { ... },
"token": "eyJhbGci...",
"refreshToken": "dGhpcyBpcyBh..."
}
Use the refresh token to get a new access token:
curl -X POST http://localhost:3000/auth/refresh \
-H "Content-Type: application/json" \
-d '{"refreshToken": "dGhpcyBpcyBh..."}'
{
"token": "eyJhbGci...(new token)",
"refreshToken": "bmV3IHJlZnJl...(new refresh token)"
}
Protecting Routes
Use the auth middleware to protect your custom routes:
// Require authentication
app.http.get("/profile", {
auth: true,
handler: async (req, res) => {
res.json(req.user);
},
});
// Require specific role
app.http.delete("/admin/users/:id", {
auth: { role: "admin" },
handler: async (req, res) => {
await app.auth.deleteUser(req.params.id);
res.json({ deleted: true });
},
});
Token Payload Structure
interface TokenPayload {
userId: string; // User's MongoDB ObjectId
email: string; // User's email
role?: string; // User's role
iat: number; // Issued at (Unix timestamp)
exp: number; // Expires at (Unix timestamp)
iss?: string; // Issuer
aud?: string; // Audience
}