核心内容摘要
HGDB数据库时区修改
颠覆认知为什么“发 Token”其实是「授权」而不是「认证」嗨开发者们在做登录功能时我们经常听到这两个词Authentication认证和Authorization授权。
很多人包括曾经的我都潜意识地认为“登录就是认证Token 是登录成功的产物所以发 Token 也是认证的一部分。
”打住这个理解其实是不准确的。
今天我们来聊聊一个架构设计中的冷知识为什么颁发 Token令牌这个动作在本质上属于「授权」️♂️
认证 vs 授权傻傻分不清楚首先我们用一个“去公司大楼上班”的例子来彻底厘清这两个概念1️⃣ 认证 (Authentication) 验明正身 场景你走到大门口保安大叔拦住你“你谁啊”动作你掏出身份证或者刷脸。
保安核对照片和本人确认你是“张三”。
核心问题你是谁(Who are you?)代码对应checkPassword(username, password)2️⃣ 授权 (Authorization) 赋予权力 场景保安确认你是张三后但他不能让你直接进去。
他拿出一张门禁卡在读写器上刷了一下写入权限可进
层然后把卡递给你。
动作发放门禁卡。
核心问题你能干什么(What can you do?)代码对应JwtUtil.createToken(userId, role)看出来了吗核对身份证是“认证”但把门禁卡Token递给你的那一刻其实是在进行“授权”。
因为那张卡代表了你在大楼里的权力。
铁证如山看看标准协议怎么说如果你还觉得那是咬文嚼字我们来看看国际标准协议OAuth
0是怎么定义的。
在 OAuth
0 中负责生成和发放 Token 的那个服务官方名称叫Authorization Server授权服务器它不叫Authentication Server也不叫Login Server。
为什么因为 Token特别是 JWT的本质就是一份“授权书”。
当你把 Token 发给客户端时你的潜台词是“我授权持有这个 Token 的人代表用户 ID: 10086在未来 2 小时内访问我的资源服务器。
”
代码视角的“解剖”在我们的 Java / Go / Node.js 代码中一个所谓的login接口其实通常原子化地执行了两个步骤publicStringlogin(Stringusername,Stringpassword){// 步骤 1认证 (Authentication)// 这一步只负责判断真假不产生 TokenUseruseruserRepo.findByName(username);if(!passwordEncoder.matches(password,user.getPassword())){thrownewAuthenticationException(密码错误);}// ✨ 步骤 2授权 (Authorization)// 这一步负责打包权限生成令牌// 这里的动作是系统授予了用户访问 API 的凭证StringtokenJwtUtil.createToken(user.getId(),user.getRole());returntoken;}步骤 1结束时系统只是知道了“你是张三”。
步骤 2结束时系统才赋予了张三“通行权”。
为什么区分这个很重要你可能会问“反正都是写在一个接口里分那么细有啥用” 在微服务和中台架构中这个区别至关重要架构解耦统一认证中心 (IAM)可能只负责验密码认证。
而业务系统可能需要根据认证结果自己发放特定业务的 Token授权。
理解 OIDCOIDC (OpenID Connect)协议之所以存在就是因为 OAuth
0 只管授权发 Token不管身份。
OIDC 补上了 ID Token才把“认证”和“授权”完美结合起来。
安全模型️理解了 Token 是授权你就明白了为什么Token 泄露 权限被盗。
因为捡到门禁卡的人拥有和你一样的权力