OAuth是一个关于授权的开放标准,在无需用户账户和密码的情况下,允许用户让第三方应用访问该用户在某一网站上存储的私密资源(比如头像、昵称、性别等),目前最新的版本是2.0。
OAuth 2.0定义了四种授权方式,详情可以参考文章
- 授权码模式(authorization code)
- 简化模式(implicit)
- 密码模式(resource owner password credentials)
- 客户端模式(client credentials)
这里只介绍授权码模式,它是最严格和最完整的一个授权过程。它要求通过申请授权的服务器与授权方的服务器互动来取得令牌(Access Token)。
下面对这些流程进行解释,App想要进行第三方登录都要事先在第三方平台申请Client ID和 Client Secret
- 点击第三方登录,带上Client ID跳转到第三方授权页面
- 在用户通过授权之后,第三方平台会对Client ID进行验证,通过验证之后返回Authorization Code作为用户认可的凭证
- 回到APP,接收到Authorization Code之后会和App的服务器进行通信,并把Authorization Code传给服务器,这时APP处于等待响应的状态
- 服务器将Authorization Code和Client Secret一起发送给第三方的服务器
- 第三方服务器通过验证之后会返回Access Token,这时OAuth流程已经结束。
- 服务器接收到Access Token之后,App服务器就可以使用Access Token作为用户授权的令牌去第三方服务平台请求用户的信息
- 第三方平台返回用户的信息,APP服务器在自己都数据库创建账户,以及用第三方平台的用户ID和自己服务器创建的ID进行关联
- APP服务器返回响应,用户登录成功。
上面就是整个流程的分析,流程比较好理解,但是为什么用户要先拿到Authorization Code而不是直接返回Access Token呢?
答案是为了安全
OAuth 2.0当初设计的目的之一不强制要求请求授权的一方使用Https,所以如果用户直接拿到Access Token,则必须把Client Secret一起发送给服务器,使用http的情况下任何的中间节点都可能遭受中间人攻击。而Client Secret是绝对要保密的。OAuth只是要求请求授权的客户端不必一定使用https,但是对于传输Access Token的服务器是要求要使用Https。通过这种一次性的Authorization Code就可以确保只有合法者才能交换Access Token,对于潜在的黑客拦截监听是无用的。