面试题答案
一键面试一般流程
- 用户登录:用户向认证服务(如登录端点)提供凭据(用户名和密码等)。
- 生成JWT:认证服务验证用户凭据。若有效,则生成JWT,该JWT包含用户身份信息(如用户名、用户ID等)、权限信息(如角色)以及其他元数据(如过期时间等),并使用密钥对JWT进行签名。
- 返回JWT:认证服务将生成的JWT返回给用户。
- 使用JWT:用户在后续请求中,将JWT包含在请求头(通常是
Authorization: Bearer <JWT>
格式)中,发送到需要访问的服务。 - 服务验证JWT:服务接收到请求后,提取JWT并验证其有效性(包括签名验证、过期时间验证等)。若验证通过,则处理请求;若不通过,则返回未授权错误。
关键组件
- 认证服务:负责验证用户凭据并生成JWT。它需要维护用户信息(如数据库存储用户名和密码),并具备生成和签名JWT的能力。
- 密钥管理:用于对JWT进行签名和验证签名。密钥需要妥善保管,防止泄露。可以使用集中式的密钥管理服务(KMS)来管理密钥。
- 受保护服务:即需要进行身份验证的服务,它们从请求中提取JWT并验证其有效性。这些服务需要与密钥管理组件交互以验证签名。
在服务间传递JWT
- 请求头传递:客户端将JWT放在请求头的
Authorization
字段中,以Bearer
模式传递,如Authorization: Bearer <JWT>
。当请求到达第一个服务后,该服务若需要调用其他服务,会将此JWT原封不动地传递到后续服务的请求头中。 - 网关/代理传递:在Kubernetes集群中,可能存在网关或代理服务。客户端请求先到达网关/代理,网关/代理验证JWT有效性(可选步骤)后,将请求连同JWT转发到后端服务。后端服务间传递JWT方式与上述相同。
验证JWT有效性
- 签名验证:服务使用与认证服务相同的密钥(或从密钥管理服务获取密钥)来验证JWT的签名。JWT库(如在Java中使用
jjwt
库,Python中使用PyJWT
库)提供验证签名的方法,若签名验证失败,则JWT可能被篡改。 - 过期时间验证:JWT中包含过期时间(
exp
字段),服务验证当前时间是否在过期时间之前。若当前时间超过过期时间,则JWT已失效。 - 其他声明验证:根据业务需求,还可能验证JWT中的其他声明,如特定的权限声明、受众声明(
aud
)等。