扫码登录流程分析

最近在公司项目中使用了钉钉网页登录,具体可参看《使用钉钉认证实现免注册登录

联想到之前也使用过微信网页登录,发现两者的操作步骤几乎一致,再查了查其它的第三方登录开发文档,基本上也是一个“套路”,它们都遵循了 OAuth 协议。

什么是OAuth协议

OAuth协议是将用户资源简易、安全地授权给指定应用的协议标准。
比如用户通过微信登录某个网站时,会将微信的头像、昵称、id等信息授权给网站。

如何授权

OAuth协议规定了4种授权模式,但是最常用的还是授权码模式,具体流程如下图所示

下面我就来具体分析授权码模式的通用步骤,并对比微信和钉钉的登录授权差异。

  1. 配置网页信息

以钉钉的开发者后台为例,关键的配置信息有3个:

  • appId。所有需要向钉钉请求资源的网站都被称之为应用,而应用id就是网站的唯一标志。
  • 回调域名。用户扫码后会跳转到这个域名下的网址,并且带上授权码参数。
  • appSecret。应用获取用户授权资源时需要对请求参数进行签名,这就是签名的密钥。是绝对不能放在浏览器端的信息。
  1. 访问授权登录页面,扫码授权
    微信扫码时会写明当前授权的应用,但钉钉目前没有说明,这一点不友好。
    这个授权登录页面访问时还要带上一些参数传递给授权服务器:
  • APP_ID。应用id,让授权服务器知道是哪个应用需要授权。
  • RESPONSE_TYPE。授权后返回的数据类型,一般选择授权码形式。
  • REDIRECT_URI。授权成功后跳回到这个网址,这个网址必须属于之前配置的回调域名。
  • STATE。可以理解为授权成功后,跳转至回调域名时传递给应用的参数,
  • SCOPE。用户将授予应用哪些权限。
  1. 授权成功,跳转至回调网址。
    这时回调网址会带上两个参数,一个是之前设置的STATE参数,另一个就是授权服务器提供的code。
    再将code发送给服务端,服务端拿到code之后的处理出现了分支。
    钉钉的做法是通过appId以及appSecret获取access_token,而微信还需要带上code参数。
    access_token并不是永久有效,一般是2小时,失效之后需要再次请求刷新access_token。

  2. 调用接口获取用户信息
    微信可以通过access_token以及openId获取用户信息了,而钉钉则比较麻烦,还需要对参数进行签名。
    这里补充一下,签名的目的一般是保证消息不被篡改,这里加上时间参数是为了防止重放攻击(短时间内多次请求),但作者觉得并无太多必要。

签名的步骤也基本相同:

  1. 将值不为空的请求参数名按照字母升序排列
  2. 以URL参数的形式进行拼接:key1=value1&key2=value2
  3. 将上述字符串通过appSecret进行签名
  4. 请求时带上签名

总结

  1. 资源提供方后台配置。
  2. 前端跳转至登录页扫码登录,并将跳转页的code传给后端。
  3. 后端获取access_token。
  4. 调用资源服务器接口获取用户数据。

参考: