{"id":18269,"library":"decentraland-crypto-middleware","title":"Decentraland Authentication Middleware","description":"Multi-framework middleware (Express, Koa, PassportJS, Well-Known Components) for authenticating HTTP requests signed with @decentraland/SignedFetch. Current stable version is 1.3.0 (June 2024), with minor releases every 6–12 months. Key differentiator: unified auth verification across Node.js web frameworks using Ethereum signature-based identity, suitable for Decentraland dApps. Supports optional verification, configurable expiration, and metadata content verification. Depends on @decentraland/crypto for signature logic.","status":"active","version":"1.3.0","language":"javascript","source_language":"en","source_url":"https://github.com/decentraland/decentraland-crypto-middleware","tags":["javascript","express","koa","passport","connect","middleware","well-known-components"],"install":[{"cmd":"npm install decentraland-crypto-middleware","lang":"bash","label":"npm"},{"cmd":"yarn add decentraland-crypto-middleware","lang":"bash","label":"yarn"},{"cmd":"pnpm add decentraland-crypto-middleware","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Core library for signature verification and auth chain parsing.","package":"@decentraland/crypto","optional":false}],"imports":[{"note":"Named export (not default). Augments request/context types with auth and authMetadata.","wrong":"import DecentralandSignatureData from 'decentraland-crypto-middleware'","symbol":"DecentralandSignatureData","correct":"import { DecentralandSignatureData } from 'decentraland-crypto-middleware'"},{"note":"Function returning Express middleware. Import individually or via namespace.","wrong":"import * as dcl from 'decentraland-crypto-middleware'; dcl.express(); // correct usage but wrong import style for the function","symbol":"express","correct":"import { express } from 'decentraland-crypto-middleware'"},{"note":"Exported as `koa`, not `koaMiddleware`. Named export.","wrong":"import { koaMiddleware } from 'decentraland-crypto-middleware'","symbol":"koa","correct":"import { koa } from 'decentraland-crypto-middleware'"},{"note":"Exported as `passport`, returns a Passport strategy constructor. Named export.","wrong":"import { passportStrategy } from 'decentraland-crypto-middleware'","symbol":"passport","correct":"import { passport } from 'decentraland-crypto-middleware'"},{"note":"Exported as `wellKnownComponents`, not abbreviated. Named export.","wrong":"import { wkc } from 'decentraland-crypto-middleware'","symbol":"wellKnownComponents","correct":"import { wellKnownComponents } from 'decentraland-crypto-middleware'"}],"quickstart":{"code":"import { express } from 'decentraland-crypto-middleware';\nimport expressApp from 'express';\n\nconst app = expressApp();\n\napp.get('/protected',\n  express(),\n  (req, res) => {\n    const address = (req as any).auth;\n    res.json({ address });\n  }\n);\n\napp.listen(3000, () => console.log('Server running on port 3000'));","lang":"typescript","description":"Sets up an Express route protected by Decentraland signature verification using the express() middleware."},"warnings":[{"fix":"Use `req: Request & DecentralandSignatureData` for correct typing.","message":"Type augmentation requires manual type intersection. `req.auth` is not typed unless you cast or use `DecentralandSignatureData`.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Remove any `expiration` option passed to middleware – it is ignored.","message":"The `verifyExpiration` option was removed in v1.0.4; expiration is now always verified.","severity":"deprecated","affected_versions":">=1.0.4"},{"fix":"Use `passport.authenticate('decentraland')` exactly.","message":"Passport strategy name must be 'decentraland'. Using a different name will fail.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Set `verifyMetadataContent: false` in options if you don't want metadata content verification.","message":"v1.3.0 added `verifyMetadataContent` option; if you pass metadata that includes content, it will now be verified by default unless opted out.","severity":"breaking","affected_versions":">=1.3.0"},{"fix":"Check for `authMetadata` existence before accessing its properties.","message":"The `authMetadata` property may be `undefined` when `optional: true` and no signature is present.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-25T00:00:00.000Z","next_check":"2026-07-24T00:00:00.000Z","problems":[{"fix":"Ensure the middleware is added to the route and if using `optional: true`, check `req.auth` for undefined.","cause":"Middleware not applied or optional mode when signature is missing.","error":"TypeError: Cannot read properties of undefined (reading 'auth')"},{"fix":"Verify that the client uses `@decentraland/SignedFetch` correctly and that the signing identity matches the expected address.","cause":"The request's authentication header contains an invalid or tampered signature.","error":"Error: Invalid signature"},{"fix":"Re-sign the request with a fresh timestamp or increase the `expiration` option (though removed in later versions, check version).","cause":"The timestamp in the signature exceeds the expiration threshold (default 10 minutes).","error":"Error: Signature expired"},{"fix":"Use `req.auth` directly as a string, not `req.auth()`.","cause":"Treating `auth` as a function instead of a string property.","error":"TypeError: req.auth is not a function"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}