资讯详情

基于 Passport.js 的 Hasura JWT 多角色认证服务:passportjs-jwt-roles 实战指南

📅 2026/9/19 22:17:10 | 华诺云谱 👁 阅读
基于 Passport.js 的 Hasura JWT 多角色认证服务:passportjs-jwt-roles 实战指南
后端API网关数据库GraphQL【免费下载链接】graphql-engineBlazing fast, instant realtime GraphQL APIs on all your data with fine grained access control, also trigger webhooks on database events.项目地址https://gitcode.com/gh_mirrors/gr/graphql-engine点击查看免费下载导读本文围绕 Hasura GraphQL Engine 官方社区仓库中的认证样板服务 passportjs-jwt-roles 展开讲解如何构建一个用户 ↔ 角色多对多关系驱动的 JWT 认证服务它在登录/注册时为用户签发携带 Hasura 专用 claimsx-hasura-allowed-roles、x-hasura-default-role等的 RS256 签名令牌使 Hasura 能够基于数据库中的user_role关联表为同一用户动态赋予多个角色。读完本文你将掌握该服务的数据库设计、环境变量配置、本地与 Docker 部署、/signup、/login、/webhook、/jwks四个端点的调用方式以及如何配置HASURA_GRAPHQL_JWT_SECRET让 Hasura 信任该服务签发的令牌。一、项目定位与设计动机这是一个认证Authentication专用的示例服务不承担业务上的用户/角色管理。它的核心特点通过 Passport.jspassport-localpassport-http-bearer实现用户名/密码登录与令牌校验将数据库user_role表映射为 JWT 中的x-hasura-allowed-roles从而支持多角色multiple roles与 Hasura 协同工作只暴露/signup创建用户刻意保持端点极简——用户与角色的管理可以交给 Hasura GraphQL 接口或任何能访问同一数据库的服务完成见 README 开头说明。从 package.json 可以看到其技术栈Express 5、Passport、Knex Objection ORM、jsonwebtoken、bcryptjs、rashaRSA 与 JWK 转换以及pg驱动连接 PostgreSQL。二、数据库 Schema三张表支撑多角色服务依赖三张表对应 db/migrations 目录下三份 Knex 迁移文件表字段说明useridUUID 主键由gen_random_uuid()自动生成20180917160913_user.jsusernameString 唯一用户唯一标识notNullablepasswordString以 bcrypt 哈希存储activeBoolean默认true为false时禁止登录created_atTimestamp默认now()roleidUUID 主键自动生成nameString 唯一角色唯一标识如user、manageruser_roleidUUID 主键自动生成role_idUUID 外键引用role.id20190127171217_user_role.jsuser_idUUID 外键引用user.id三张表构成经典的多对多关联。在 db/schema.js 中User模型通过 Objection 的ManyToManyRelation经user_role连接表关联Role并在getRoles()中把数据库角色映射为角色名列表getRoles() { return this.roles.map(el el.name).concat(user) }注意这里始终追加user角色——即每个用户至少拥有user角色可被视作兜底默认角色。密码在$beforeInsert()钩子中用 bcryptjs 加盐哈希后落库db/schema.js登录时通过verifyPassword()用bcrypt.compare校验。三、环境变量与密钥配置服务通过环境变量完成全部配置详见 README 的 Environment variables 一节环境变量作用默认行为AUTH_PRIVATE_KEY用于 JWT 签名的 RSA 私钥多行需用\n转义未设置时读取private.pem文件config/jwt.jsAUTH_PUBLIC_KEY用于输出 JWK 集合的 RSA 公钥多行需用\n转义未设置时读取public.pem文件AUTH_KEY_ID标识当前签名密钥的kid未设置时基于公钥生成 128 位 FNV 哈希config/jwt.jsDATABASE_URLPostgreSQL 连接串格式postgres://username:passwordhost:port/database_name回退到postgres://postgres:localhost:5432/postgresknexfile.jsPORT服务监听端口默认8080app.jsREADME 特别警告仓库中的 RSA 密钥示例仅供开发严禁用于生产环境。四、本地开发部署步骤按 README 的 Deploy locally 一节执行# 安装 NPM 依赖 npm install # 生成 RSA 密钥对 openssl genrsa -out private.pem 2048 openssl rsa -in private.pem -pubout public.pem # 以转义格式打印密钥供环境变量使用 awk -v ORS\\n 1 private.pem awk -v ORS\\n 1 public.pem # 配置数据库连接 export DATABASE_URLpostgres://postgres:localhost:5432/postgres # 执行迁移会创建 user、role、user_role 三张表 knex migrate:latest # 启动服务 npm startknex migrate:latest将应用 db/migrations 下的三份迁移。启动后控制台会输出✓ App is running at http://localhost:8080app.js。五、Docker 生产部署README 给出镜像构建命令docker build . -t hasura/passportjs-jwt-roles:latestDockerfile 基于node:24-alpine仅安装生产依赖npm install --onlyproduction暴露8080端口并以npm start启动。运行镜像时需传入第二节的环境变量尤其是DATABASE_URL与 RSA 密钥。六、配置 Hasura GraphQL Engine服务签发 RS256 JWT因此 Hasura 端需设置HASURA_GRAPHQL_JWT_SECRET。两种方式任选方式一直接提供 PEM 公钥README Configure the Hasura GraphQL Engine 一节{ type: RS256, key: AUTH_PUBLIC_KEY }AUTH_PUBLIC_KEY为 PEM 格式 RSA 公钥换行需以\n转义。方式二JWKS 模式{ type: RS256, jwk_url: hostname:port/jwks }Hasura 通过jwk_url从认证服务的/jwks端点拉取公钥集合JWK Set。该端点由 controllers/user.js 的getJwks实现用rasha.importSync({ pem: publicKey })将 PEM 公钥转为 JWK并补充alg: RS256、use: sig与kid字段。README 提示以AUTH_PUBLIC_KEY环境变量喂给 JWKS 的功能当时尚未完全就绪使用前请以当前仓库代码实际行为为准。七、API 端点使用路由定义见 app.js共四个端点7.1 注册/signupcurl -H Content-Type: application/json \ -d{username: test123, password: test123, confirmPassword: test123} \ http://localhost:8080/signupsignupValidatorscontrollers/user.js要求用户名非空、密码长度至少 4 位、confirmPassword与password一致校验失败返回 400 及错误数组。成功后响应示例来自 README{ id: 907f0dc7-6887-4232-8b6e-da3d5908f137, username: test123, roles: [user], token: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9... }7.2 登录/logincurl -H Content-Type: application/json \ -d{username: test123, password: test123} \ http://localhost:8080/loginpostLogin先做loginValidators校验再通过passport.authenticate(local, ...)完成认证controllers/user.js。passport-local策略config/passport.js按用户名查库、校验active状态与 bcrypt 密码成功后返回与/signup相同结构的用户信息含 JWT。7.3 Webhook 模式/webhook服务亦可作为 Hasura 的Webhook 认证后端使用curl -H Content-Type: application/json \ -d{username: test123, password: test123} \ http://localhost:8080/loginREADME 中该请求示例与/login相同实际使用时应将/login返回的 token 作为 Bearer 令牌传给/webhook。getWebhookcontrollers/user.js通过passport-http-bearer策略校验令牌并返回 Hasura claims令牌无效返回 401无令牌时返回{ X-Hasura-Role: anonymous }以支持匿名角色。7.4 JWK 集合/jwkscurl http://localhost:8080/jwks返回标准 JWK Set 结构{ keys: [ ... ] }供 Hasura 的jwk_url模式拉取验证密钥。八、JWT 载荷与 Hasura Claims 结构JWT 的生成集中在User.getJwt()db/schema.jsconst signOptions { subject: this.id, expiresIn: 30d, // 30 天有效期 algorithm: RS256 } const claim { name: this.username, https://hasura.io/jwt/claims: this.getHasuraClaims() } return jwt.sign(claim, jwtConfig.key, signOptions)Hasura 约定将权限声明放在https://hasura.io/jwt/claims命名空间下由getHasuraClaims()生成db/schema.jsgetHasuraClaims() { return { x-hasura-allowed-roles: this.getRoles(), x-hasura-default-role: user, x-hasura-user-id: ${this.id} } }各 claim 含义x-hasura-allowed-roles该用户被允许使用的角色数组来自user_role关联表并恒追加userHasura 据此判定用户可切换哪些角色x-hasura-default-role未显式指定角色时的默认角色userx-hasura-user-id用户 ID可在 Hasura 权限规则如{user_id: {_eq: X-Hasura-User-Id}}中引用。文件里还保留了x-hasura-org-id、x-hasura-custom的注释示例说明可按需扩展自定义 claims。README 中的示例 JWT 载荷解码后可见sub为用户 ID、exp为 30 天后的过期时间与上述实现吻合。九、已知限制与后续方向README 的 Limitations 一节明确列出保持事实陈述未在 Heroku 上测试过除创建不带特定角色的单用户外无内置用户/角色管理作者通过前端应用走 Hasura GraphQL 端点操作同一数据库完成仅支持单把 RSA 密钥不做密钥轮换不处理 JWT 过期与密钥更换暂不支持 Google、GitHub 等第三方 OAuth 登录——设计初衷是作为代理查询数据库中的用户角色后为 Hasura 附加 claims尚无自动化测试package.json 中test脚本为占位未来可考虑将端点通过 Hasura remote schema 暴露而非直接暴露给客户端。十、可继续探索的仓库资源服务实现app.js、config/jwt.js、config/passport.js数据模型与 claims 生成db/schema.js数据库迁移db/migrations错误处理db/errors.js同仓库其他认证样板auth-webhookspassport-js 为本文服务的灵感来源更完整的认证方案可参考 auth-servers 目录下的其他实现以及架构文档 architecture 中对 Hasura 认证机制的说明。赞分享后端API网关数据库GraphQL【免费下载链接】graphql-engineBlazing fast, instant realtime GraphQL APIs on all your data with fine grained access control, also trigger webhooks on database events.项目地址https://gitcode.com/gh_mirrors/gr/graphql-engine点击查看免费下载相关推荐LTX-2训练优化技巧如何减少显存占用并提升训练效率的8个方法LTX 2训练优化技巧如何减少显存占用并提升训练效率的8个方法 LTX 2作为首个基于DiT的音频 视频生成模型在训练过程中可能会面临显存占用大、训练速度慢人工智能大模型基础模型媒体生成视频音频多模态预训练微调Higress jwt-auth 插件实战指南基于 JWT 的 API 网关认证与授权Higress jwt auth 插件实战指南基于 JWT 的 API 网关认证与授权 导读 jwt auth 是 Higress 内置的认证类 Wasm 插API网关后端云原生LLM 网关人工智能MCP 服务Higress simple-jwt-auth 插件实战基于 wasm-go 的 JWT Token 解析认证指南Higress simple jwt auth 插件实战基于 wasm go 的 JWT Token 解析认证指南 simple jwt auth 是 HigAPI网关后端云原生LLM 网关人工智能MCP 服务创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。