概念

开放授权(OAuth)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。

OAuth允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。每一个令牌授权一个特定的网站(例如,视频编辑网站)在特定的时段(例如,接下来的2小时内)内访问特定的资源(例如仅仅是某一相册中的视频)。这样,OAuth让用户可以授权第三方网站访问他们存储在另外服务提供者的某些特定信息,而非所有内容。

OAuth是OpenID的一个补充,但是完全不同的服务。

详解

OAuth是一个关于授权(authorization)的开放网络标准,在全世界得到广泛应用,目前的版本是2.0版。

OAuth 2.0 是目前最流行的授权机制,用来授权第三方应用,获取用户数据。

客户端的 4 种授权模式

客户端必须得到用户的授权(authorization grant),才能获得令牌(access token)。OAuth 2.0定义了四种授权模式。

  • 授权码模式(authorization code)

    这种方式是最常用的流程,安全性也最高,它适用于那些有后端的 Web 应用。如微信小程序的授权登录,code 相当于授权码,access token 相当于令牌。

    它的特点就是通过客户端的后台服务器,与"服务提供商"的认证服务器进行互动。

    基本流程:

    1. 客户端(app / 浏览器)将用户导向第三方认证服务器
    2. 用户在第三方认证服务器,选择是否给予客户端授权
    3. 用户同意授权后,认证服务器将用户导向客户端事先指定的 重定向URI,同时附上一个授权码。
    4. 客户端将授权码发送至服务器,服务器通过授权码以及 APP_SECRET 向第三方服务器申请 access_token
    5. 服务器通过 access_token,向第三方服务器申请用户数据,完成登录流程
  • 简化模式(implicit)

  • 密码模式(resource owner password credentials)

    对于我们自己的客户端,比如 Larabbs 网站的 IOS 客户端,中间的授权码流程就显得有些多余,这时 OAuth2 的另一个模式 —— 密码模式,就很好的解决了这个问题。

    对于我们自己的客户端,用户应该直接在客户端中输入用户名和密码,客户端直接通过用户数据的用户名和密码获取 access_token 即可。

    密码模式流程如下:

    1. 用户在客户端输入用户名和密码;
    2. 客户端提交用户名,密码,client_id 和 client_secret 到服务器;
    3. 服务器直接返回 access_token;
    4. 可以看到密码模式的流程非常简洁,我们可以方便的向自己的客户端发出访问令牌,而不需要遍历整个 OAuth2 授权代码重定向流程。
  • 客户端模式(client credentials)

总结一下

对于 APP 第三方登录来说有两种实现方法

  1. APP_SECRET 存储在客户端,客户端获取授权码之后,直接通过授权码和 APP_SECRET 去第三方换取 access_token。
  2. APP_SECRET 存储在服务端,客户端获取授权码之后,将授权码发送给服务器,服务器通过授权码和 APP_SECRET 去第三方换取 access_token。(推荐)

微信网页授权的流程

  1. 微信发起 OAuth 的跳转地址

    https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

  2. 获取 access_token

    https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

  3. 通过 access token 获取个人信息

    https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN

参考文章

OAuth 2.0 的一个简单解释

OAuth 2.0 的四种方式