Express, Hono and other servers
Verify session tokens in any JavaScript server.
@daywalker/auth/server works in Node.js, Bun, Deno and edge runtimes. You need two values:
bash
DAYWALKER_PUBLISHABLE_KEY=pk_test_...
DAYWALKER_AUTH_URL=https://users.daywalker.devExpress
ts
import express from "express";
import { verifyToken } from "@daywalker/auth/server";
const app = express();
async function requireAuth(req, res, next) {
const token = req.headers.authorization?.replace(/^Bearer /, "");
const session = await verifyToken(token, {
publishableKey: process.env.DAYWALKER_PUBLISHABLE_KEY!,
frontendApi: process.env.DAYWALKER_AUTH_URL!,
authorizedParties: ["https://app.example.com"], // where your frontend runs
});
if (!session) return res.status(401).json({ error: "Not signed in" });
req.userId = session.userId;
next();
}
app.get("/notes", requireAuth, async (req, res) => {
res.json(await db.notes.findMany({ where: { ownerId: req.userId } }));
});Hono
ts
import { Hono } from "hono";
import { verifyToken } from "@daywalker/auth/server";
const app = new Hono<{ Variables: { userId: string } }>();
app.use("/api/*", async (c, next) => {
const session = await verifyToken(c.req.header("authorization")?.slice(7), {
publishableKey: c.env.DAYWALKER_PUBLISHABLE_KEY,
frontendApi: c.env.DAYWALKER_AUTH_URL,
});
if (!session) return c.json({ error: "Not signed in" }, 401);
c.set("userId", session.userId);
await next();
});NestJS guard
ts
import { CanActivate, ExecutionContext, Injectable, UnauthorizedException } from "@nestjs/common";
import { verifyToken } from "@daywalker/auth/server";
@Injectable()
export class AuthGuard implements CanActivate {
async canActivate(ctx: ExecutionContext) {
const req = ctx.switchToHttp().getRequest();
const session = await verifyToken(req.headers.authorization?.slice(7), {
publishableKey: process.env.DAYWALKER_PUBLISHABLE_KEY!,
frontendApi: process.env.DAYWALKER_AUTH_URL!,
});
if (!session) throw new UnauthorizedException();
req.userId = session.userId;
return true;
}
}About verifyToken
- It returns
nullfor any bad, expired or foreign token, so a simpleif (!session)is enough. - It throws if the public keys can't be fetched (for example, the auth service is unreachable). That way an outage shows up as an error, not as everyone silently being signed out.
authorizedPartiesis optional but recommended. It rejects tokens issued to a different app on the same instance.
Other languages
Session tokens are standard ES256 JWTs. Any JWT library can verify them. Use these settings:
- JWKS URL:
<auth url>/i/<instance id>/.well-known/jwks.json - Issuer:
<auth url>/i/<instance id> - Algorithm:
ES256only. Reject everything else. - Required claims:
sub(user ID),sid(session ID),exp,iat
For the issuer, the instance ID is encoded inside your publishable key. In JavaScript, instanceIdFromKey(pk) from @daywalker/auth decodes it.