express-bearer-token
Express middleware that extracts RFC 6750 bearer tokens from request body, query, headers, or cookies.
Repository Health
Technical Analysis
express-bearer-token is a lightweight Express middleware that implements RFC 6750 bearer token extraction. It inspects incoming requests for an access token in the request body, query string, the Authorization header, or an optional cookie, and exposes the found value on req.token for downstream handlers to consume.
The middleware enforces RFC 6750’s requirement that a token appear in only one location per request, responding with HTTP 400 if it detects the same token supplied in multiple places. Every extraction point — body key, query key, header scheme, cookie key, and the property name the token is bound to — is configurable, and optional support for signed cookies lets it integrate with cookie-parser-based session setups.
What You Get
- RFC 6750-compliant extraction of access_token from body, query string, or Authorization: Bearer header
- Optional cookie-based token lookup with support for signed cookies via cookie-parser
- A configurable options object to rename bodyKey, queryKey, headerKey, reqKey, and cookie settings
- Automatic 400 response when a token is supplied in more than one location, per RFC 6750
- Bundled TypeScript type definitions for the middleware and its options
Common Use Cases
- Protecting a REST API endpoint that accepts bearer tokens from either an Authorization header or a query parameter for browser-based clients
- Accepting tokens via signed cookies for server-rendered apps that also expose a JSON API
- Normalizing token extraction ahead of a custom authentication/authorization middleware
Under The Hood
Architecture
The package is a single-file factory: index.js exports one function that takes an options object and returns an Express (req, res, next) handler closure. Inside the closure, the code sequentially checks req.query, req.body, req.headers.authorization, and — if a cookie option is set — req.headers.cookie (parsed via the cookie package and optionally decoded with cookie-parser’s signedCookie), tracking a shared token/error pair of local variables across the branches. If the token was found in more than one location it short-circuits with a 400 response; otherwise it assigns req[reqKey] and calls next(). There is no internal layering beyond this one function plus a tiny cookie-lookup helper, which is appropriate for its scope but means every consumer’s request pipeline is coupled to this single execution path — any change to the precedence or conflict logic affects all call sites identically.
Tech Stack
Plain CommonJS JavaScript with no build step or bundler; the package ships hand-written index.d.ts type definitions alongside untranspiled JS. Runtime dependencies are minimal — cookie for parsing the raw Cookie header and cookie-parser’s exported signedCookie helper for validating signed cookies — with no direct dependency on Express itself beyond the request/response object conventions it expects. Tests run under Mocha and Chai (mocha -R spec test), with cookie-signature as a dev-only dependency used to hand-sign cookies in test fixtures. CI is configured via a legacy .travis.yml.
Code Quality
test.js covers ten scenarios spanning body/query/header extraction, custom key names, signed and unsigned cookies, custom reqKey binding, and the RFC 6750 conflict-abort case — solid scenario coverage for the module’s small surface area. However, the entire middleware factory in index.js is wrapped in a top-level try/catch that only console.errors a caught exception without calling next(err) or otherwise surfacing it, so an unexpected error (e.g. a malformed cookie during parsing) would silently hang the request instead of failing loudly. The codebase is untyped plain JavaScript (types are retrofitted via a community-maintained .d.ts file), lint configuration is a minimal legacy .jshintrc rather than ESLint, and CI runs on an largely inactive Travis setup with no coverage reporting.
API Design
The middleware exposes a single factory function with a flat options object (bodyKey, queryKey, headerKey, reqKey, cookie), requiring zero configuration for the RFC 6750 default case (app.use(bearerToken())) while still letting every extraction point be renamed for non-compliant APIs. The README documents the default case, custom keys, and both signed and unsigned cookie modes with runnable snippets, and the bundled TypeScript definitions carry inline comments describing each option. There is no dedicated docs site, examples directory, or migration guide beyond the README and CHANGELOG, and the swallowed top-level exception means misconfiguration tends to fail silently rather than surface a clear error to the integrator.