我们做了个网站,想让用户用微信登录。问题来了——用户在微信里已经有账号了,我们不想再管一套密码,用户也懒得注册。怎么办?

前两篇我们讲了 session 和 JWT,但它们有个共同前提:用户得把密码交给我们。我们自己当爹,管注册、管存储、管找回密码。可如果用户已经有微信账号了,他凭什么再把密码给你?

这里要区分两个概念:认证(Authentication)是”你是谁”,授权(Authorization)是”你能干嘛”。OAuth 2.0 本质上是一个授权框架——它让用户可以授权第三方应用访问自己在某个平台上的资源,而不需要把密码给出去

四个角色

OAuth 里有四个角色,搞清楚它们,后面的东西就好理解了:

  • 用户(Resource Owner):微信用户,资源(头像、昵称)的主人
  • 客户端(Client):我们的网站,想用微信登录的那方
  • 授权服务器(Authorization Server):微信的服务器,负责验证用户身份、发令牌
  • 资源服务器(Resource Server):微信的 API 服务器,拿着令牌才能拿到用户信息

有些平台授权服务器和资源服务器是同一台,但概念上它们是两回事。

授权码模式:你去物业拿钥匙

OAuth 最常用的流程是授权码模式(Authorization Code)。用个比喻就好懂了:

你去朋友家拿东西,但朋友不在家。你不是直接撬锁,而是去物业证明身份,物业给你一张单次通行证,你拿着通行证去物业换钥匙,再用钥匙开门。

具体流程:

  1. 我们的网站把用户跳转到微信的授权页面
  2. 用户在微信页面上点”同意授权”
  3. 微信把用户重定向回来,URL 里带一个授权码(code)
  4. 我们的服务端用这个 code 去微信换一个 access_token
  5. 拿着 access_token 调微信 API,拿到用户信息

第 3 步的 URL 长这样:https://oursite.com/callback?code=AUTH_CODE_HERE

为什么要有授权码这一步,不直接给 token?因为授权码是在前端 URL 里传的,暴露了也没关系——它只能用一次,而且必须加上 app_secret 才能换 token。你想想,如果 token 直接出现在浏览器地址栏里,那不是谁都能截获?

微信登录和 GitHub 登录有啥区别?

本质流程一模一样,都是授权码模式。但细节上有差别:

  • 微信用的是自己的 OAuth 2.0 变体,返回的 access_token 和 openid 分开处理,接口风格比较”中国特色”
  • GitHub是标准 OAuth 2.0,文档清晰,参数名都是 client_idclient_secretcode 这些

对接微信登录的时候,你会拿到一个 appidsecret,然后拼一个授权链接:https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_userinfo

GitHub 的话:https://github.com/login/oauth/authorize?client_id=xxx&scope=read:user

看到没?参数名不同,但逻辑相同。

安全上要注意什么?

两个坑特别容易踩:

第一,state 参数。 授权服务器回调你的时候,会把 state 原样带回来。你在发起请求时生成一个随机值存到 session 里,回来的时候比对一下——防 CSRF 攻击。没有 state,攻击者可以把自己的授权码绑到你的账号上。

第二,redirect_uri 校验。 微信和 GitHub 都要求你在后台配置合法的回调地址。这不是摆设——如果不校验,攻击者可以构造一个恶意 redirect_uri,把授权码劫走。

另外,access_token 要存在服务端,千万别返回给前端。前端拿到的应该是我们自己签发的 session 或 JWT。

从 session 到 JWT 到 OAuth

回头看这三篇,其实是一条演进线:

session 解决了”记住用户”的问题,但要存服务端状态,分布式时代不好使。JWT 把状态放到客户端,解决了扩展性,但”谁来管密码”这个问题它没回答。OAuth 则更进一步——连密码都不用你管了,用户在第三方平台完成认证,你只管拿令牌做事。

这三层不是互相替代的关系,而是层层递进。实际项目里,你很可能三样都在用:OAuth 让用户用微信登录,登录之后我们签发 JWT 做后续鉴权,某些场景下还得用 session 管理。

用户永远不想多记一套密码,而我们永远不想多管一套密码。OAuth 就是那个让双方都满意的方案。