怎样给面试官通俗易懂的讲解oauth2.0中的授权码模式 注意:要使用QQ登录博客园的例子

好的,授权码模式是OAuth 2.0四种模式中最安全、最常用的一种。下面我用“QQ登录博客园”这个你熟悉的场景,分四步讲清楚。


先打个比方:就像“开支票”

在讲流程之前,先打个比方帮你建立直觉。

假设你想让朋友帮你去银行取1000块钱,但你不可能把银行卡密码告诉他。正确的做法是:你开一张1000元的支票给他,他拿着支票去银行,银行验证支票是真的,就把钱给他。

OAuth 2.0的授权码模式,干的就是类似的事:

  • = 用户(资源所有者)
  • 朋友 = 博客园(第三方应用)
  • 银行 = QQ(授权服务器 + 资源服务器)
  • 支票 = 授权码(code)
  • 银行最终给的钱 = 访问令牌(access_token)

四步走:QQ登录博客园完整流程

第一步:博客园把你“踢”到QQ去

你在博客园登录页,点击“QQ登录”按钮。

这时候,博客园的服务器会生成一个特殊的链接,让你的浏览器跳转到QQ的授权页面。这个链接里带了三个关键信息:

  • client_id:博客园在QQ互联平台注册时拿到的“身份证号”,告诉QQ“我是博客园”
  • redirect_uri:QQ授权成功后该把用户送回博客园的哪个地址(回调地址)
  • response_type=code:告诉QQ“我要用授权码模式”

对应标准流程的步骤(A) :客户端将用户导向认证服务器。

第二步:你在QQ页面登录并授权

浏览器跳转到QQ的登录页面后,你输入QQ号和密码,登录QQ。

登录成功后,QQ会问你:“博客园想要获取你的昵称和头像,你同意吗?”你点击“同意授权”。

对应标准流程的步骤(B) :用户登录并同意授权。

第三步:QQ给你一个“授权码”,把你送回博客园

你同意授权后,QQ的服务器会做两件事:

  1. 生成一个授权码(code) ——这就是那张“支票”
  2. 把你的浏览器重新导向回博客园,并且在网址后面带上这个授权码,比如:https://www.cnblogs.com/callback?code=ABC123

注意:这个授权码有几个特点:

  • 只能用一次,用过就失效
  • 有效期很短(QQ规定10分钟内有效)
  • 不是最终访问用户信息的令牌,只是一张“换票凭证”

对应标准流程的步骤(C) :授权服务器生成授权码,通过回调地址返回给客户端。

第四步:博客园后台拿授权码去QQ换“访问令牌”

现在浏览器已经回到博客园页面了,但真正的授权还没完成

博客园的前端页面只是一个“展示层”,接下来最关键的一步在博客园的后台服务器上发生:

  1. 博客园的后台拿到浏览器传过来的授权码 ABC123
  2. 博客园后台偷偷地(不经过浏览器)向QQ的服务器发一个请求,说:“我是博客园,这是我的client_idclient_secret(密码),我手里有用户给的授权码ABC123,请给我访问令牌”
  3. QQ服务器验证授权码有效、验证博客园身份无误后,返回一个访问令牌(access_token) 给博客园后台

对应标准流程的步骤(D)和(E) :客户端用授权码向授权服务器申请令牌,拿到令牌。

拿到了令牌,然后呢?

博客园拿到访问令牌后,就可以用这个令牌去QQ的资源服务器请求用户信息了——比如你的QQ昵称、头像等。

拿到这些信息后,博客园就知道“哦,原来是用户小明用QQ登录了”,于是帮你在博客园创建一个账号或者直接登录成功。

总结:为什么要搞得这么复杂?

你可能觉得绕了一大圈,为什么不直接让博客园拿你的QQ号和密码去查?

核心原因就一个:安全。

如果博客园直接拿你的QQ密码,万一博客园被黑客攻击,你的QQ密码就泄露了。而用授权码模式:

  1. 你的QQ密码只在QQ的页面上输入,博客园从头到尾都接触不到
  2. 授权码通过浏览器传递,但真正的令牌是在后台服务器之间交换的,不会暴露在浏览器里
  3. 你可以控制授权范围(比如只给昵称头像,不给好友列表)
  4. 令牌有过期时间,而且可以随时撤销

这就是为什么你在各大网站看到的“QQ登录”“微信登录”“GitHub登录”,背后用的都是这套授权码模式。

面试时可以这样一句话总结

“授权码模式就像先用一张临时支票(授权码)换真正的取款凭证(访问令牌) ,而不是直接把银行卡密码(QQ密码)交给第三方。QQ登录博客园就是典型:博客园把你导向QQ授权页,你登录同意后QQ给你一个code,博客园后台再用这个code去QQ换token,最后用token拿你的信息。整个过程你的密码始终只给QQ,博客园拿不到。”

这个问题问得很精准,说明你在思考实际落地的细节。


是不是用户每次请求都会携带上accesstoken

答案是:“不是”所有浏览器发起的请求都带,但“所有需要访问用户私有资源”的请求,都必须带。

为了让你在面试时讲清楚,我把“带不带”拆成三种场景,你一听就明白了:

1. 哪些“请求”绝对不带?

用户纯浏览公开内容时,不带。

比如你登录博客园之后,去看一篇不需要登录的技术文章。这个请求是浏览器直接向博客园的Web服务器发起的,目的是拿HTML页面。这个请求里没有Access Token,因为博客园只需要返回公开的网页内容,不需要知道你是谁。


2. 哪些“请求”必须带?

前端(浏览器)调用后端API接口时,必须带。

比如你在博客园登录后,想修改自己的个人简介,或者查看“我的收藏”。此时,博客园的前端代码(JavaScript)会向后端API发一个Ajax请求(比如 GET /api/myinfo)。

这个请求必须带上Access Token,通常放在 HTTP请求头(Header) 里,像这样:

Authorization: Bearer eyJhbGciOiJIUzI1NiIs...(你的token)

因为博客园的后端服务器不认识你的浏览器了(HTTP是无状态的),它必须靠这个Token来验证:“这个请求确实是QQ那边认证过的用户小明发来的”。

面试加分点:你可以强调,绝对不会放在URL参数里(比如 ?token=xxx),因为浏览器地址栏、历史记录和服务器日志都会暴露Token,极不安全。标准做法是放在 Header 中。


3. “每次”的边界是什么?(Token过期了怎么办?)

既然每次调用接口都要带,那如果Token过期了,用户岂不是每隔一小时就要重新输一遍QQ密码?

实际情况是这样处理的:

  • 博客园拿到QQ给的 access_token 时,同时还会拿到一个 refresh_token(刷新令牌)
  • access_token 有效期短(比如1小时),refresh_token 有效期长(比如30天)。
  • 当用户操作时,博客园后台发现“咦,这个Token过期了”,它会自动拿着 refresh_token 去QQ那里换一个新的 access_token,然后后端拿着新Token去处理用户的请求。
  • 对用户来说,他完全无感知,只需要在浏览器里正常点击“保存个人简介”即可。

用“QQ登录博客园”的例子串一遍:

  1. 登录时:你授权后,博客园后台拿到了Token,存起来(存到Session里,或者返回给前端存到内存/本地存储里)。
  2. 你在博客园写评论:你的浏览器发请求给博客园后端,带上Token。后端看到Token,知道是你,于是保存这条评论。
  3. 你在博客园看首页推荐:浏览器请求只是拿HTML,不带Token,因为看推荐不需要知道你是谁。
  4. 你一小时后修改头像:浏览器带上过期的Token去请求,博客园后台发现过期,自动用refresh_token换新Token,然后继续帮你改头像。整个过程你甚至不知道Token换过一次。

面试时一句话总结:

Access Token不是像Cookie那样每个网页请求都自动携带,而是只在客户端(浏览器/App)调用需要用户身份认证的后端API接口时,主动放在HTTP请求头里带过去。 不带Token的只用于获取公开数据,而Token过期则通过Refresh Token静默刷新,所以用户感觉不到‘每次’携带的负担。”

posted on 2026-08-24 16:02  ~码铃薯~  阅读(11)  评论(0)    收藏  举报

导航