指南:Node (Express)
步骤 1:从请求头中提取 Bearer 令牌
一个授权 (Authorization) 请求应包含一个 Authorization
头,其内容为 Bearer <access_token>
。从请求头中提取授权令牌:
// auth_middleware.ts
import { IncomingHttpHeaders } from 'http';
const extractBearerTokenFromHeaders = ({ authorization }: IncomingHttpHeaders) => {
const bearerTokenIdentifier = 'Bearer';
if (!authorization) {
throw new Error({ code: 'auth.authorization_header_missing', status: 401 });
}
if (!authorization.startsWith(bearerTokenIdentifier)) {
throw new Error({ code: 'auth.authorization_token_type_not_supported', status: 401 });
}
return authorization.slice(bearerTokenIdentifier.length + 1);
};
步骤 2:令牌验证
为了演示,我们使用 jose 包来验证令牌的签名、过期状态和所需声明。
安装 jose
作为你的依赖
npm i jose --save
获取 Logto 的 OIDC 配置
你将需要一个 JWK 公钥集和令牌发行者来验证接收到的 JWS 令牌的签名和来源。所有最新的公共 Logto 授权 (Authorization) 配置可以在 https://<your-logto-domain>/oidc/.well-known/openid-configuration
找到。
例如,调用 https://tenant-id.logto.app/oidc/.well-known/openid-configuration
。并在响应体中找到以下两个字段:
{
"jwks_uri": "https://tenant-id.logto.app/oidc/jwks",
"issuer": "https://tenant-id.logto.app/oidc"
}
添加认证 (Authentication) 中间件
Jose 的 jwtVerify
方法可以帮助你验证令牌的 JWS 格式、令牌签名、发行者、受众和过期状态。如果验证失败,将抛出异常。
注意:
如果你使用 基于角色的访问控制 (RBAC),还需要进行权限 (Scope) 验证。
// auth-middleware.ts
import { createRemoteJWKSet, jwtVerify } from 'jose';
//...
export const verifyAuthFromRequest = async (req, res, next) => {
// 提取令牌
const token = extractBearerTokenFromHeaders(req.headers);
const { payload } = await jwtVerify(
token, // 从请求头中提取的原始 Bearer 令牌
createRemoteJWKSet(new URL('https://<your-logto-domain>/oidc/jwks')), // 使用从 Logto 服务器查询的 jwks_uri 生成 jwks
{
// 令牌的预期发行者,应由 Logto 服务器发行
issuer: 'https://<your-logto-domain>/oidc',
// 预期的受众令牌,应为当前 API 的资源指示器
audience: '<your request listener resource indicator>',
}
);
// 如果你使用 RBAC
assert(payload.scope.includes('some_scope'));
// 自定义 payload 逻辑
userId = payload.sub;
return next();
};
将中间件应用于你的 API
import { verifyAuthFromRequest } from '/middleware/auth-middleware.ts';
app.get('/user/:id', verifyAuthFromRequest, (req, res, next) => {
// 自定义代码
});
相关资源
使用 JWT 和 Logto 保护你的 Express.js API