开发者社区 问答 正文

前后端分离架构下JWT认证该如何设计

在前后端分离的架构下JWT认证该如何设计?

展开
收起
_all_is_well 2021-10-22 16:53:55 964 分享 版权
阿里云 AI 助理回答

在前后端分离的架构下,JWT(JSON Web Token)认证的设计需要从前端、后端以及网关或中间层的角度进行综合考虑。以下是基于知识库资料的详细设计建议:


1. 前端设计

前端负责生成认证请求、存储Token以及在业务请求中携带Token。

1.1 用户登录与Token获取

  • 用户登录:前端通过表单或API接口向后端授权服务发送用户名和密码。
  • Token缓存:授权服务验证用户信息后,使用私钥生成JWT Token并返回给前端。前端需将Token缓存到本地(如localStoragesessionStorage),以便后续请求使用。

1.2 请求中携带Token

  • Token位置
    • Header:推荐使用Authorization: Bearer {token}的方式携带Token。
    • Query参数:适用于GET请求,但不推荐,因为Token可能被记录在日志中。
    • Cookie:适合需要自动管理Token的场景,但需注意跨域问题。
  • Token刷新:如果Token有过期时间(exp字段),前端需实现Token刷新机制,通常通过刷新Token接口获取新的Token。

2. 后端设计

后端主要负责Token的签发、验证以及业务逻辑处理。

2.1 授权服务

  • Token签发

    • 使用私钥(如RSA或ECDSA算法)生成JWT Token。
    • Token中应包含必要的用户信息(如subaudexp等标准Claim)。
    • 示例代码(Python):
    import jwt
    import time
    
    private_key = """-----BEGIN PRIVATE KEY-----
    ... (私钥内容)
    -----END PRIVATE KEY-----"""
    
    payload = {
        "sub": "user_id",  # 用户标识
        "aud": "client_id",  # 受众
        "exp": int(time.time()) + 3600,  # 过期时间
        "iat": int(time.time()),  # 签发时间
    }
    
    token = jwt.encode(payload, private_key, algorithm="RS256")
    print(token)
    

2.2 Token验证

  • 公钥验证
    • 后端通过配置的JWKS(JSON Web Key Set)中的公钥对Token进行验证。
    • 验证内容包括签名有效性、过期时间(exp)、受众(aud)等。
  • 防重放攻击
    • 可通过jti字段实现防重放检查,确保每个Token只能使用一次。

2.3 业务逻辑处理

  • 验证通过后,后端从Token中提取用户信息(如subroles等),并根据这些信息执行业务逻辑。

3. 网关或中间层设计

在前后端分离架构中,网关或中间层可以作为统一的认证入口,减轻后端服务的压力。

3.1 JWT认证插件

  • API网关
    • 配置JWT认证插件,支持从Header、Query参数、Cookie中读取Token。
    • 支持多个JWK(JSON Web Key),允许为不同客户端配置不同的公钥。
    • 示例配置(YAML格式):
    jwks:
      keys:
        - alg: "RS256"
          e: "AQAB"
          kty: "RSA"
          n: "qSVxcknOm0uCq5vGsOmaorPDzHUubBmZZ4UXj-9do7w9X1uKFXAnqfto4TepSNuYU2bA_-tzSLAGBsR-BqvT6w9SjxakeiyQpVmexxnDw5WZwpWenUAcYrfSPEoNU-0hAQwFYgqZwJQMN8ptxkd0170PFauwACOx4Hfr-9FPGy8NCoIO4MfLXzJ3mJ7xqgIZp3NIOGXz-GIAbCf13ii7kSStpYqN3L_zzpvXUAos1FJ9IPXRV84tIZpFVh2lmRh0h8ImK-vI42dwlD_hOIzayL1Xno2R0T-d5AwTSdnep7g-Fwu8-sj4cCRWq3bd61Zs2QOJ8iustH0vSRMYdP5oYQ"
    
  • 函数计算
    • 在HTTP触发器或自定义域名中启用JWT认证,配置JWKS以验证Token。

3.2 Claim转发

  • 网关可将Token中的Claim(如subroles)映射为后端服务所需的参数,并通过Header、Query参数或表单参数传递给后端。

4. 安全性增强

为了提升JWT认证的安全性,需注意以下几点:

4.1 Token有效期

  • 设置合理的Token过期时间(exp),避免长期有效的Token被滥用。
  • 实现Token刷新机制,确保用户无需频繁重新登录。

4.2 防重放攻击

  • 在Token中添加唯一标识符(jti),并在网关或后端记录已使用的jti,防止Token被重复使用。

4.3 HTTPS传输

  • 强制使用HTTPS:确保Token在传输过程中不会被窃取。

4.4 公钥轮换

  • 定期更新公钥和私钥,避免密钥泄露导致的安全风险。

5. 示例流程

以下是一个完整的JWT认证流程示例:

  1. 用户登录

    • 前端发送用户名和密码到授权服务。
    • 授权服务验证用户信息,生成JWT Token并返回给前端。
  2. 业务请求

    • 前端在请求Header中携带Authorization: Bearer {token}
    • 网关或后端验证Token的有效性。
  3. Token验证

    • 网关使用JWKS中的公钥验证Token签名。
    • 检查Token的expaud等字段是否有效。
  4. 请求转发

    • 验证通过后,网关将请求转发给后端服务。
    • 后端服务根据Token中的Claim执行业务逻辑。

6. 注意事项

  • Token存储安全:避免将Token存储在易被窃取的地方(如URL参数)。
  • 跨域问题:如果使用Cookie存储Token,需配置CORS策略。
  • 性能优化:对于高频请求,可通过缓存公钥或Token验证结果来提升性能。

通过上述设计,您可以构建一个安全、高效的JWT认证系统,满足前后端分离架构的需求。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答