Express 5용 Better Auth: 인증 라우트 마운트와 requireAuth로 API 보호
코드파일 3개컨텍스트약 405토큰검사 통과
설치
$
genpm add @yohangel/auth-express포함 내용
- src/lib/auth-express/에 소스 코드, 파일 3개. (4.3kB)
- src/lib/auth-express/AGENTS.md에 AI 규칙, 그리고 IDE 규칙 파일.
- @yohangel/auth을(를) 자동으로 해결합니다.
README
이 패키지에는 README가 없습니다.
약 405토큰→ src/lib/auth-express/AGENTS.md→ .cursor/rules/genpm-yohangel-auth-express.mdc
이것이 AI가 src/lib/auth-express에서 작업할 때 읽는 내용 그대로입니다. 그 외에는 컨텍스트에 아무것도 추가되지 않습니다.
@yohangel/auth-express — rules for AI agents
Purpose
Connects @yohangel/auth to Express 5: mounts Better Auth on /api/auth/* and provides requireAuth / optionalAuth middleware that put the session in res.locals.
Module map
index.ts—mountAuth(app, opts),requireAuth,optionalAuth,AuthLocalstype,createAuthre-export.
Integration (do this after installing)
- Order matters — mount auth BEFORE body parsers:
import express from 'express'; import { mountAuth, requireAuth } from './lib/auth-express/index.js'; const app = express(); mountAuth(app, { sendEmail }); // /api/auth/* app.use(express.json()); app.get('/api/me', requireAuth, (req, res) => res.json({ id: res.locals.user.id })); - Frontend on another origin:
app.use(cors({ origin: ['https://app.example.com'], credentials: true }))beforemountAuth, and list that origin inAUTH_TRUSTED_ORIGINS. - Behind a proxy/CDN set
app.set('trust proxy', 1)andAUTH_IP_HEADERso rate limits use the real client IP. - Express 4 is not supported (route syntax
*splatis Express 5). Project must be ESM ("type": "module").
Conventions
- Protect routes with
requireAuth; readres.locals.user/res.locals.session(typed byAuthLocals). - Authorization (who can do what) goes in your handlers after
requireAuth, never on the client.
Don't
- Don't put
express.json()beforemountAuth(Better Auth must read the raw body). - Don't use
cors({ origin: '*', credentials: true }). - Don't return
res.locals.session(contains the token) to the client.
# @yohangel/auth-express — rules for AI agents
## Purpose
Connects `@yohangel/auth` to Express 5: mounts Better Auth on `/api/auth/*` and provides `requireAuth` / `optionalAuth` middleware that put the session in `res.locals`.
## Module map
- `index.ts` — `mountAuth(app, opts)`, `requireAuth`, `optionalAuth`, `AuthLocals` type, `createAuth` re-export.
## Integration (do this after installing)
1. Order matters — mount auth BEFORE body parsers:
```ts
import express from 'express';
import { mountAuth, requireAuth } from './lib/auth-express/index.js';
const app = express();
mountAuth(app, { sendEmail }); // /api/auth/*
app.use(express.json());
app.get('/api/me', requireAuth, (req, res) => res.json({ id: res.locals.user.id }));
```
2. Frontend on another origin: `app.use(cors({ origin: ['https://app.example.com'], credentials: true }))` before `mountAuth`, and list that origin in `AUTH_TRUSTED_ORIGINS`.
3. Behind a proxy/CDN set `app.set('trust proxy', 1)` and `AUTH_IP_HEADER` so rate limits use the real client IP.
4. Express 4 is not supported (route syntax `*splat` is Express 5). Project must be ESM (`"type": "module"`).
## Conventions
- Protect routes with `requireAuth`; read `res.locals.user` / `res.locals.session` (typed by `AuthLocals`).
- Authorization (who can do what) goes in your handlers after `requireAuth`, never on the client.
## Don't
- Don't put `express.json()` before `mountAuth` (Better Auth must read the raw body).
- Don't use `cors({ origin: '*', credentials: true })`.
- Don't return `res.locals.session` (contains the token) to the client.
.genpmignore 적용 후 주입될 정확한 트리입니다. 고정 대상:
// @yohangel/auth-express — Better Auth en Express 5. Monta las rutas ANTES de express.json() y protege rutas con
// `requireAuth`. La sesión queda en `res.locals.session` / `res.locals.user`.
import { fromNodeHeaders, toNodeHandler } from 'better-auth/node';
import type { Express, NextFunction, Request, RequestHandler, Response } from 'express';
import { type AuthSession, type CreateAuthOptions, createAuth, getAuth } from '../auth/index.js';
export { createAuth };
/** Crea la instancia (si no existe) y monta /api/auth/* (Express 5: `*splat`). Llamar antes de `express.json()`. */
export function mountAuth(app: Express, opts: CreateAuthOptions & { basePath?: string } = {}): void {
const { basePath = '/api/auth', ...authOpts } = opts;
const auth = createAuth(authOpts);
app.all(`${basePath}/*splat`, toNodeHandler(auth));
}
export type AuthLocals = { session: AuthSession['session'] | null; user: AuthSession['user'] | null };
async function load(req: Request, res: Response): Promise<AuthSession | null> {
const s = await getAuth().api.getSession({ headers: fromNodeHeaders(req.headers) });
res.locals.session = s?.session ?? null;
res.locals.user = s?.user ?? null;
return s;
}
/** 401 JSON si no hay sesión válida. */
export const requireAuth: RequestHandler = async (req: Request, res: Response, next: NextFunction) => {
try {
if (!(await load(req, res))) {
res.status(401).json({ error: 'unauthorized' });
return;
}
next();
} catch (e) {
next(e);
}
};
/** Carga la sesión si existe, sin bloquear. */
export const optionalAuth: RequestHandler = async (req, res, next) => {
try {
await load(req, res);
next();
} catch (e) {
next(e);
}
};
이 패키지는 MCP 서버를 선언하지 않습니다.
| 버전 | 커밋 | 게시일 | 검사 |
|---|---|---|---|
| 1.0.0 | 7145b9d | 3시간 전 | ✔ 검사 통과 |
- npm
- 없음
- 제안됨
- GenPM은 npm 명령을 제안하고, 동의한 경우에만 실행합니다.
- 검사
- 검사 통과 · 문제 0건
- 커밋
- auth-express@1.0.0 → 7145b9d58055b5145085782c958b7577f1d65276 · 가져온 뒤 검증됨
- 스크립트
- 없음. GenPM은 패키지 코드를 절대 실행하지 않습니다.
- 라이선스
- MIT
- 신고
- 문제가 있나요?