Bearer
@vafast/bearer extracts the Bearer token from the request per RFC6750 and injects it into the route context via next({ bearer }).
It does not verify signatures or authorize: when no token is found, bearer is undefined and no 401 is returned automatically. The verification logic is up to you (for example with @vafast/jwt).
Installation
npm install @vafast/bearerQuick Start
import { Server, defineRoute, defineRoutes, err, json, serve } from 'vafast'
import { bearer } from '@vafast/bearer'
const routes = defineRoutes([
defineRoute({
method: 'GET',
path: '/profile',
middleware: [bearer()],
handler: ({ bearer: token }) => {
if (!token) throw err.unauthorized('Missing Bearer token')
return json({ token })
},
}),
])
const server = new Server(routes)
serve({ fetch: server.fetch, port: 3000 })Usage
Basic Usage
Extraction order (stops at the first match):
Authorizationheader: matches theheaderprefix (defaultBearer), then takes the token after it- Query parameter: field name defaults to
access_token - Request body: for non-
GETrequests, reads the field viaparseBody, defaultaccess_token
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...Or:
GET /profile?access_token=eyJhbGciOiJIUzI1NiJ9...Common Scenarios
1. Mount Globally
const server = new Server(routes)
server.use(bearer())Every route handler can destructure bearer (it is undefined when no token is sent).
2. Custom Field Names (Non-Standard APIs)
server.use(
bearer({
extract: {
header: 'Token',
query: 'token',
body: 'token',
},
}),
)This matches Authorization: Token <value>, or ?token= / body { "token": "..." }.
3. Extract, Then Verify with JWT
import { jwt } from '@vafast/jwt'
import { bearer } from '@vafast/bearer'
import { err, json } from 'vafast'
const jwtMiddleware = jwt({ secret: process.env.JWT_SECRET!, exp: '1h' })
type JwtRequest = Request & {
jwt: {
verify: (token?: string) => Promise<{ userId?: string } | false>
}
}
defineRoute({
method: 'GET',
path: '/me',
middleware: [jwtMiddleware, bearer()],
handler: async ({ req, bearer: token }) => {
const payload = await (req as JwtRequest).jwt.verify(token)
if (!payload) throw err.unauthorized('Invalid token')
return json({ userId: payload.userId })
},
})4. Use getBearer in Deeper Logic
After the middleware has run, you can also read it from the request locals:
import { getBearer } from '@vafast/bearer'
defineRoute({
method: 'GET',
path: '/debug',
middleware: [bearer()],
handler: ({ req }) => json({ token: getBearer(req) }),
})API
Exports
| Export | Description |
|---|---|
bearer | Factory function that returns the middleware |
getBearer | Reads the extracted token from req.__locals.bearer |
BearerOptions | Options type |
default | Same as bearer |
Options / Parameters
bearer(options?: BearerOptions)| Parameter | Type | Default | Description |
|---|---|---|---|
extract.body | string | 'access_token' | Field name for the token in the JSON body |
extract.query | string | 'access_token' | Field name for the token in the query |
extract.header | string | 'Bearer' | Authorization prefix (followed by a single space and the token) |
Omitting options is equivalent to all the defaults above.
Related Functions
getBearer(req: Request): string | undefined
Reads the locals written by the middleware. Returns undefined if bearer() hasn't run yet.
Best Practices
- Prefer the
Authorizationheader in production; query / body are for compatibility with legacy clients - Separate extraction from verification: this package only extracts; verify signatures with JWT or other logic
- When the token is missing, return explicitly with
err.unauthorized/json(..., 401), addingWWW-Authenticateas needed - Body parse failures are silently ignored; don't rely on a malformed body for auth error messages
Notes
- The token is injected into the context (
next({ bearer })), notreq.bearer - The header value is only used when
Authorizationstarts with the configuredheaderprefix GETrequests never attempt to parse the body- The body is read via
req.clone()+parseBodyto avoid consuming the original request stream