简单解释

一个大型居民小区,采用封闭式管理。小区是有门禁的,每个业主都是有自己的门禁卡可以自由出入小区。但是,外卖员和快递员因为不属于小区的业主,所以他们是没有门禁卡可以随意进入小区的。
此时,为了方便快递员和外卖员可以方便送货和送餐,业主们就可以和小区的物业做好协商,在门禁系统上设置一个”获取进入小区”权限的按钮,外卖员和快递员只要按下这个按钮,去申请进入小区的权限,业主就可以远程给外卖员和快递员进入小区的权限。
门禁系统在得到业主的确认后,就会给外卖员和快递员一个进入小区的令牌(access token),令牌类似密码的一串数字,只在短期内(比如7天)有效。外卖员和快递员就可以向门禁系统输入令牌,进入小区。

使用令牌而不是直接远程给快递员开门的原因是,可能接下来几天快递院每天都会过来送货,此时就可以一直复用这个令牌进入小区。

互联网场景

居民小区就是用户数据的网络服务,比如,微信存储的好友列表,获取这些信息,就必须经过微信的”门禁系统”。
快递员,外卖员其实就是第三方应用,想要穿过门禁系统,进入小区。
业主,其实就是同意授权第三方应用的系统应用。

令牌

令牌是短期的,到期会自动失效。用户无法修改。
令牌可以被数据所有者撤销,会立即失效。
令牌可以有权限范围。比如只能进小区的二号门。对于网络服务来说,只读令牌比读写令牌更安全。

获取令牌的方式

授权码

第三方应用先申请一个授权码,然后再用该码获取令牌。
安全性高,适用于后端的web应用。授权码通过前端传送,令牌则是存储在后端,而且所有与资源服务器的通信都在后端完成,这样的前后端分离,可以避免令牌泄漏。

(1)A(AI助手)网站提供一个链接,用户点击后就会跳转到B(微信公众号)网站,B网站授权数据给A网站使用。

  1. https://b.com/oauth/authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=CALLBACK_URL&scope=read
  2. response_type: 要求返回授权码(code)
  3. client_id 哪个客户端在请求b系统
  4. redirect_uri: b系统接收或拒绝请求后跳转网址
  5. scope: 表示授权的范围(这里是只读)

(2)用户跳转后,B网站会要求用户登录,然后询问是否同意给予A网站授权。用户表示同意,这是B网站就会调回 redirect_uri 参数指定的网址。跳转时,会传回一个授权码。

  1. https://a.com/callback?code=AUTHORIZATION_CODE
  2. code 授权码

(3)A网站拿到授权码后,就可以在其后端接口中,向B网站请求令牌

  1. https://b.com/oauth/token?client_id=CLIENT_ID&client_secret=CLIENT_SECRET&grant_type=authorization_code&code=AUTHORIZATION_CODE&redirect_uri=CALLBACK_URL
  2. client_id & client_secret : 用来让B(微信)确认A(AI助手)的身份
  3. client_secret: 参数数保密的,因此只能在后端发请求
  4. grant_type: 参数的值是 AUTHORIZATION_CODE, 表示采用的授权方式是授权码
  5. code: 是从第(2)步拿到的授权码
  6. redirect_uri: 令牌颁发后的回调地址

(4)B网站收到请求后,就会颁发令牌,具体做法是向 redirect_uri 指定的网址,发送一段JSON数据,然后从JSON数据里面就可以拿到 access_token 令牌。

image.png