白话理解什么是OAuth 2.0

OAuth 2.0概念

最近在开发鉴权功能,类似下面的截图(apifox系统的截图),开发到OAuth 2.0方式的时候,遇到一点麻烦,于是简单的梳理了一下。下面用生动的例子讲解一下OAuth 2.0。

角色设定:

  • 你(勇敢的冒险者): 你拥有一些珍贵的魔法卷轴和神器,存放在你的个人宝库中。
  • 魔法宠物训练师公会(Client Application): 这是一个想要训练你的魔法宠物(比如小火龙、独角兽)的公会,他们需要查阅你的一些魔法卷轴(获取宠物训练知识)和使用你的某些神器(进行特殊训练)。
  • 你的守护神龙(Authorization Server & Resource Server): 这条龙负责守护你的宝库。它既负责验证"魔法宠物训练师公会"是否有资格查看你的卷轴和使用你的神器(Authorization Server),也实际保管着这些宝物(Resource Server)。

OAuth 2.0 的流程就像一场精心设计的授权仪式:

  1. "魔法宠物训练师公会"的请求信函(Authorization Request):

    "魔法宠物训练师公会"想要为你训练宠物,他们会给你送来一封盖有公会印章的正式信函,信中详细说明了他们需要查阅哪些魔法卷轴(例如,《初级火焰掌控》、《独角兽心灵沟通》)以及需要使用哪些神器(例如,"元素共鸣水晶"、"精神力放大镜"),并请求你允许他们访问。

    想象一下: 公会就像一群专业的宠物训练师,他们知道如何让你的宠物变得更强大。但他们不能直接闯入你的宝库拿东西,必须先礼貌地请求你的许可。这封信就是他们的正式请求,列出了他们需要的"工具"和"知识"。

  2. 你前往神龙的居所进行授权(Authorization Grant):

    你收到信函后,觉得"魔法宠物训练师公会"看起来很靠谱,也希望他们能帮助你的宠物成长。于是,你亲自前往守护神龙的居所,向它说明了"魔法宠物训练师公会"的请求,并告知神龙你愿意授权他们访问特定的卷轴和神器。

    想象一下: 你来到了守护你宝库的强大神龙面前,告诉它:"这些训练师想要借阅这些卷轴和使用这些神器来训练我的宠物,我觉得可以信任他们。"

  3. 守护神龙授予"授权印记"(Authorization Code):

    守护神龙听取了你的意愿后,不会直接把宝库的钥匙交给公会,而是给你一个特殊的、一次性的"授权印记"。这个印记上刻有特定的魔法符文,代表着你已经同意授权"魔法宠物训练师公会"进行访问,但这个印记本身并不能打开宝库。你需要把这个"授权印记"交给公会。

    想象一下: 神龙理解了你的意思,于是给你一个闪烁着魔法光芒的"授权印记",告诉你:"把这个交给那些训练师,他们拿着这个才能来我这里换取真正的通行令牌。"

  4. "魔法宠物训练师公会"用"授权印记"换取"访问龙鳞"和"刷新龙鳞"(Access Token & Refresh Token Request):

    "魔法宠物训练师公会"收到了你给予的"授权印记"后,会带着这个印记,以及他们公会的徽章和秘钥(Client ID 和 Client Secret),来到守护神龙面前,请求兑换能够真正进入宝库的凭证。他们用"授权印记"作为他们获得你授权的证明。守护神龙验证了"授权印记"和公会的身份后,会授予他们一块临时的"访问龙鳞"(Access Token),这块龙鳞在一段时间内具有魔法效力,可以让他们进入宝库并使用被授权的卷轴和神器。

    为了方便他们后续的操作,神龙通常还会授予他们一块更珍贵的"刷新龙鳞"(Refresh Token)。当"访问龙鳞"的魔法效力快要消失时,公会可以使用"刷新龙鳞"再次来请求新的"访问龙鳞",而不需要你再次亲自授权。

    想象一下: 训练师公会带着"授权印记"和他们的公会信物来到神龙面前,说:"勇敢的冒险者已经同意我们查阅这些卷轴和使用这些神器了,这是他给我们的授权印记。"神龙核实后,给了他们一块闪耀着光芒的"访问龙鳞",这块龙鳞在一段时间内允许他们进入宝库。同时,神龙还给了他们一块更古老的"刷新龙鳞",以便他们在"访问龙鳞"失效后再次申请。

  5. "魔法宠物训练师公会"使用"访问龙鳞"进入宝库(Access Protected Resource):

    现在,"魔法宠物训练师公会"拥有了"访问龙鳞",他们就可以凭借这块龙鳞进入你的宝库,查阅你授权的魔法卷轴,并使用你授权的神器来训练你的魔法宠物。每次进入宝库或者使用神器时,他们都需要出示这块"访问龙鳞",证明他们获得了你的许可。

    想象一下: 训练师们拿着"访问龙鳞",就可以自由出入你的宝库中被授权的区域,学习卷轴上的知识,并使用那些强大的神器来帮助你的宠物提升能力。

  6. "访问龙鳞"魔力消退,使用"刷新龙鳞"再次请求(Refresh Token Usage):

    当"访问龙鳞"的魔法效力快要消失时,"魔法宠物训练师公会"可以使用"刷新龙鳞"再次来到守护神龙面前,请求一块新的"访问龙鳞",而不需要再次让你亲自跑来授权。守护神龙会验证"刷新龙鳞"的有效性,并颁发新的"访问龙鳞"。

    想象一下: 当"访问龙鳞"的光芒逐渐暗淡,快要失效时,训练师们可以使用更珍贵的"刷新龙鳞"再次来到神龙面前,说:"我们的'访问龙鳞'快失效了,这是我们拥有的'长期授权凭证',请允许我们继续工作。"神龙验证后,会再次赐予他们一块新的"访问龙鳞"。

这个奇幻的例子更形象地展示了 OAuth 2.0 的核心流程:

  • 授权请求(Request): 表达需求。
  • 授权授予(Grant): 冒险者同意。
  • 授权码(Code): 临时的授权凭证。
  • 访问令牌(Access Token): 短期有效的"通行证"。
  • 刷新令牌(Refresh Token): 用于获取新"通行证"的"长期凭证"。
  • 资源访问(Resource Access): 使用"通行证"进入宝库。

OAuth 2.0设计

概念讲解完毕,我们继续沿用"勇敢的冒险者"、"魔法宠物训练师公会"和"守护神龙"的奇幻世界设定,这次我们更细致地描述每次请求和响应中可能包含的关键字段。

1. "魔法宠物训练师公会"的请求信函(Authorization Request):

当"魔法宠物训练师公会"想要获得授权时,他们发送给你的"请求信函"中(或者在用户界面上引导你跳转到守护神龙的授权页面时,构建的URL会包含以下关键信息):

  • response_type : 明确告知守护神龙他们希望获取的是授权码(通常设置为 code)。
  • client_id: "魔法宠物训练师公会"在守护神龙那里注册时获得的唯一身份标识,就像他们的公会徽章编号。
  • redirect_uri: 当守护神龙完成授权后,应该将你(冒险者)导回的"魔法宠物训练师公会"的地址(通常是他们的App或网站的一个特定页面)。这就像告诉神龙,授权完成后把你送回哪个营地。
  • scope : 请求的权限范围,明确他们需要访问哪些魔法卷轴和神器。例如:read:scrolls:fire, use:artifact:resonance. 这就像在信中详细列出他们需要哪些"工具"和"知识"。
  • state (可选但推荐): 一个由"魔法宠物训练师公会"生成的随机字符串,用于防止跨站请求伪造(CSRF)攻击。这就像信封上的一个特殊防伪标记,用于验证响应的真实性。

你(冒险者)在守护神龙的居所同意授权后,守护神龙会进行处理。

2. 守护神龙授予"授权印记"(Authorization Code):

当你同意授权后,守护神龙会将你重定向回 "魔法宠物训练师公会"提供的 redirect_uri,并在URL中附带"授权印记"和 state(如果请求中包含):

  • code: 这就是守护神龙颁发的临时"授权印记",是一个一次性的授权码。
  • state (如果请求中包含): 守护神龙会原样返回 "魔法宠物训练师公会"在请求中发送的 state 值,用于让公会验证响应的合法性。

3. "魔法宠物训练师公会"用"授权印记"换取"访问龙鳞"和"刷新龙鳞"(Access Token Request):

"魔法宠物训练师公会"的后台服务器会向守护神龙的授权服务器发送一个 POST 请求,请求体中通常包含以下字段:

  • grant_type : 明确告知守护神龙他们正在使用授权码来换取令牌(设置为 authorization_code)。
  • code: 你(冒险者)给予他们的"授权印记"。
  • redirect_uri : 必须与在授权请求中使用的 redirect_uri 完全一致,用于验证请求的来源。
  • client_id: "魔法宠物训练师公会"的公会徽章编号。
  • client_secret: "魔法宠物训练师公会"在守护神龙那里注册时获得的秘密密钥,就像只有公会高层才知道的秘密咒语,用于证明自己的身份。这个密钥需要保密存储,绝不能泄露给冒险者或其他人。

守护神龙验证通过后,会返回包含"访问龙鳞"和"刷新龙鳞"的 JSON 响应:

JSON

json 复制代码
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ik1hZ2ljUGV0VHJhaW5lciIsImlhdCI6MTY4MjcwMDAwMH0.signature",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "long_lived_refresh_token_string",
  "scope": "read:scrolls:fire use:artifact:resonance"
}
  • access_token: 这就是临时的"访问龙鳞",是一个字符串(通常是 JWT 格式),用于访问受保护的资源。
  • token_type : 令牌类型,通常是 Bearer
  • expires_in: 访问令牌的有效期,单位通常是秒(例如,3600 秒 = 1 小时)。
  • refresh_token: 这就是更珍贵的"刷新龙鳞",用于在访问令牌过期后获取新的访问令牌。
  • scope: 再次声明了授予的权限范围。

4. "魔法宠物训练师公会"使用"访问龙鳞"进入宝库(Access Protected Resource):

当"魔法宠物训练师公会"想要访问你的魔法卷轴或神器时,他们会在发送给守护神龙的资源服务器的 HTTP 请求头中携带"访问龙鳞":

makefile 复制代码
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ik1hZ2ljUGV0VHJhaW5lciIsImlhdCI6MTY4MjcwMDAwMH0.signature

守护神龙的资源服务器会验证这个"访问龙鳞"的有效性,如果有效,则返回请求的资源(例如,魔法卷轴的内容或允许使用神器的权限)。

5. "访问龙鳞"魔力消退,使用"刷新龙鳞"再次请求(Refresh Token Usage):

当"魔法宠物训练师公会"的"访问龙鳞"快要过期时,他们的后台服务器会向守护神龙的授权服务器发送一个 POST 请求,请求体中包含:

  • grant_type : 明确告知守护神龙他们正在使用刷新令牌来获取新的访问令牌(设置为 refresh_token)。
  • refresh_token: 他们之前获得的"刷新龙鳞"。
  • client_id: 他们的公会徽章编号。
  • client_secret: 他们的秘密咒语。

守护神龙验证通过后,会返回一个新的包含"访问龙鳞"(通常也会包含一个新的"刷新龙鳞")的 JSON 响应:

JSON

json 复制代码
{
  "access_token": "new_access_token_string",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "new_refresh_token_string"
}
  • access_token: 新的临时"访问龙鳞"。
  • token_type: 令牌类型。
  • expires_in: 新访问令牌的有效期。
  • refresh_token (可选,但常见): 有时刷新令牌也会被轮换,返回一个新的刷新令牌。

通过这个更详细的例子,你应该能更清晰地看到 OAuth 2.0 协议中每次请求和响应中涉及的关键字段,以及它们在整个授权流程中的作用。这就像一场精心设计的魔法仪式,每一步都有特定的咒语和信物(字段)进行沟通和验证。

访问令牌和刷新令牌

"访问龙鳞"(Access Token)和"刷新龙鳞"(Refresh Token)的特性和使用场景。

"访问龙鳞"(Access Token):短暂而强大的魔法通行证

  • 特性:

    • 魔法效力有限: "访问龙鳞"拥有强大的魔法力量,能够让你("魔法宠物训练师公会")在一段时间内自由出入冒险者(你)的宝库,并使用被授权的魔法卷轴和神器。但是,这种魔法效力是有限的,就像龙的吐息,虽然强大但不能持久。
    • 针对特定资源: 一块"访问龙鳞"通常只被授予访问特定范围的资源。例如,一块"访问龙鳞"可能只允许查阅火焰相关的卷轴和使用元素共鸣水晶,而不能查看水系卷轴或使用其他神器。这就像宝库的不同区域需要不同的魔法钥匙。
    • 携带方便但需谨慎: "访问龙鳞"通常以一种紧凑的形式(例如,一块刻有符文的玉佩)交给"魔法宠物训练师公会",方便他们在每次访问宝库时出示。但由于其强大的力量,一旦落入坏人之手,可能会被滥用,所以需要谨慎保管。
    • 无状态验证: 守护神龙(资源服务器)在验证"访问龙鳞"时,通常不需要每次都去查询自己的数据库。令牌本身可能包含足够的信息(例如,通过 JWT 格式),通过验证其签名即可确认其有效性和所拥有的权限。这就像神龙只需要感知龙鳞上的魔法气息是否正确,而不需要翻阅厚厚的授权记录。
  • 使用场景:

    • 日常资源访问: "魔法宠物训练师公会"在训练你的魔法宠物时,需要频繁地查阅卷轴和使用神器,他们会每次都出示"访问龙鳞"来获得操作权限。这就像工人每次进入你家的不同房间进行装修时,都需要出示临时的"工作凭证"。
    • API 调用授权: 如果"我的云相册"(在这个奇幻的比喻里是守护神龙的宝库)对外提供 API 接口,"照片美化大师"("魔法宠物训练师公会")在调用这些 API 接口时,通常会在请求头中携带"访问龙鳞"作为授权凭证。

"刷新龙鳞"(Refresh Token):续订魔法通行证的古老信物

  • 特性:

    • 魔法效力持久: "刷新龙鳞"的魔法效力比"访问龙鳞"持久得多,它就像一个古老的信物,代表着守护神龙对"魔法宠物训练师公会"的长期信任(在你授权的前提下)。
    • 用于获取新的"访问龙鳞": "刷新龙鳞"本身并不能直接用于访问受保护的资源。它的唯一作用是向守护神龙的授权服务器申请新的、临时的"访问龙鳞"。这就像"长期居住证明"本身不能开门,但可以用来去物业管理处换取新的门禁卡。
    • 保管要求更高: 由于"刷新龙鳞"能够续订"访问龙鳞",其重要性更高,因此"魔法宠物训练师公会"需要更加安全地保管它,防止被窃取。一旦泄露,坏人可能会利用它不断地获取新的"访问龙鳞",从而持续访问你的宝库。
    • 可能存在使用次数或时间限制: 虽然有效期较长,但为了安全起见,"刷新龙鳞"也可能存在使用次数限制或者一个更长的总有效期。例如,一块"刷新龙鳞"可能只能使用一定次数来获取新的"访问龙鳞",或者在一段时间后彻底失效,需要重新获取。
  • 使用场景:

    • 静默续订访问令牌: 当"访问龙鳞"即将过期时,"魔法宠物训练师公会"的后台程序可以使用"刷新龙鳞"在用户无感知的情况下向守护神龙请求一个新的"访问龙鳞",从而保证用户操作的连续性,无需重新登录。这就像工人的临时"工作凭证"快过期时,他可以使用"长期居住证明"悄悄地去物业管理处换取新的凭证,而不需要打扰你。
    • 长时间保持连接: 对于需要长时间保持与资源服务器连接的应用,"刷新龙鳞"可以确保在"访问龙鳞"过期后能够自动续订,维持连接状态。

为什么需要两者?

  • 安全性与便利性的平衡: 使用短期有效的"访问龙鳞"降低了令牌泄露的风险。即使"访问龙鳞"被盗,其有效期有限,造成的损害也较小。而使用长期有效的"刷新龙鳞"则可以在"访问龙鳞"过期后,在用户无需再次交互的情况下获取新的"访问龙鳞",提升了用户体验。
  • 权限控制: 可以对"访问龙鳞"的权限范围进行更精细的控制,确保第三方应用只能访问其需要的资源。而"刷新龙鳞"本身不具备访问资源的能力,只是一个"续订凭证"。
  • 风险隔离: 即使"刷新龙鳞"被盗,由于它不能直接访问资源,其危害比一个永久有效的、可以直接访问所有资源的令牌要小。同时,可以采取额外的安全措施来保护"刷新龙鳞",例如更严格的存储和使用限制。

总而言之,"访问龙鳞"就像一把临时的、有权限的钥匙,用于日常的资源访问;而"刷新龙鳞"则像一个可以帮你定期更换这把钥匙的长期凭证,在保证安全性的前提下,提供了更好的用户体验。两者协同工作,共同构建了安全且便捷的授权机制。

刷新令牌安全问题

想象一下,这块"刷新龙鳞"不仅仅是一块普通的龙鳞,它蕴含着古老的魔法和守护神龙的某种承诺。

"刷新龙鳞"的奥秘与力量:

  • 古老契约的象征: 这块"刷新龙鳞"不仅仅是一个凭证,它更像是你(勇敢的冒险者)与守护神龙之间签订的一个长期契约的象征。当你第一次授权"魔法宠物训练师公会"时,守护神龙不仅给予了他们临时的"访问龙鳞",还赋予了他们这块更珍贵的"刷新龙鳞",代表着在你的允许下,他们可以在未来一段时间内,无需再次惊扰你,也能通过神龙重新获得进入你宝库的许可。
  • 维系信任的纽带: "刷新龙鳞"的存在,维系着你、守护神龙和"魔法宠物训练师公会"三者之间的信任关系。你信任神龙能够妥善管理你的授权,神龙信任你最初的授权意愿,而公会则持有这块信物,以便在需要时能够继续获得服务。
  • 沉睡的魔法能量: 与活跃的"访问龙鳞"不同,"刷新龙鳞"本身并不直接释放强大的魔法力量来打开宝库。它的力量是沉睡的,只有当"魔法宠物训练师公会"带着它,并以正确的方式(连同他们的公会徽章和秘钥)来到守护神龙面前时,神龙才会感应到这股古老的契约力量,并重新激活,赋予他们新的"访问龙鳞"。
  • 谨慎使用的权利: 拥有"刷新龙鳞"就像拥有了一种特殊的权利,可以在"访问龙鳞"失效后再次请求。但这种权利并非没有限制。守护神龙可能会记录下"刷新龙鳞"的使用频率和时间,如果发现异常(例如,在短时间内被多次使用),可能会暂时冻结甚至永久剥夺这块"刷新龙鳞"的力量,以防止滥用。

"刷新龙鳞"的保管与风险:

想象一下,"刷新龙鳞"如果被"哥布林盗贼团"(恶意攻击者)窃取,会发生什么?

  • 无需你的许可,持续入侵: 哥布林盗贼团可以拿着这块"刷新龙鳞"偷偷溜到守护神龙那里,谎称自己是"魔法宠物训练师公会",并不断地请求新的"访问龙鳞",从而在一段时间内自由进出你的宝库,偷走你的珍贵卷轴和神器,而你可能毫不知情。这就像小偷拿到了你的长期居住证明,不断地去物业那里领取新的门禁卡。
  • 难以追踪的恶意行为: 由于哥布林盗贼团每次都使用新获取的"访问龙鳞"进行非法访问,追踪他们的真实身份和行为会更加困难。你可能只会发现宝库里的东西在不断减少,但很难确定是谁做的。
  • 信任体系的破坏: "刷新龙鳞"的泄露不仅会危及你的宝物,也会破坏你对守护神龙和"魔法宠物训练师公会"的信任。你会开始怀疑他们的安全措施是否足够,以及你的授权是否被妥善管理。

守护神龙的应对之策(针对刷新令牌的安全措施):

为了保护"刷新龙鳞"和你的宝库,守护神龙会采取多种魔法和策略:

  • 魔法封印与标记: 在颁发"刷新龙鳞"时,神龙会在其上施加特殊的魔法封印和标记,用于识别其合法来源和所属的"魔法宠物训练师公会"。当收到请求时,神龙会仔细检查这些封印和标记是否完好无损。
  • 气息追踪与记录: 神龙可能会记录下每次颁发"刷新龙鳞"时的魔法气息和请求者的某些特征(例如,使用的魔法能量波动)。在后续收到使用该"刷新龙鳞"的请求时,神龙会比对这些记录,如果发现气息异常,则会拒绝请求。
  • 设置警戒魔法: 在宝库周围设置警戒魔法,如果短时间内出现大量来自同一"刷新龙鳞"的访问请求,就会触发警报,提醒神龙注意可能存在的异常情况。
  • 定期更换"刷新龙鳞": 为了进一步提高安全性,守护神龙可能会在一段时间后,要求"魔法宠物训练师公会"重新进行授权流程,颁发一块新的"刷新龙鳞,使旧的失效。这就像定期更换你家的长期居住证明。
  • 响应异常撤销魔法: 如果你(冒险者)发现"刷新龙鳞"可能被泄露,你可以告知守护神龙,神龙会立即施展强大的撤销魔法,使该"刷新龙鳞"永久失效。

后面我会实现整个功能。

相关推荐
小小小小宇16 分钟前
手写 zustand
前端
Hamm1 小时前
用装饰器和ElementPlus,我们在NPM发布了这个好用的表格组件包
前端·vue.js·typescript
小小小小宇2 小时前
前端国际化看这一篇就够了
前端
大G哥2 小时前
PHP标签+注释+html混写+变量
android·开发语言·前端·html·php
whoarethenext2 小时前
html初识
前端·html
小小小小宇2 小时前
一个功能相对完善的前端 Emoji
前端
m0_627827522 小时前
vue中 vue.config.js反向代理
前端
Java&Develop2 小时前
onloyoffice历史版本功能实现,版本恢复功能,编辑器功能实现 springboot+vue2
前端·spring boot·编辑器
白泽talk2 小时前
2个小时1w字| React & Golang 全栈微服务实战
前端·后端·微服务
摆烂工程师2 小时前
全网最详细的5分钟快速申请一个国际 “edu教育邮箱” 的保姆级教程!
前端·后端·程序员