OAuth2.0协议及演示服务搭建

在这里插入图片描述

OAuth2.0协议

应用场景

  • 我想登陆某个网站(比如人人网),但是嫌注册新账户太麻烦,我用QQ账户直接进行登陆。
    在这里插入图片描述
  • 扩展场景:
    • "云冲印"的网站,可以将用户储存在Google的照片,冲印出来。用户为了使用该服务,必须让"云冲印"读取自己储存在Google上的照片。

传统方法及弊端

  • 传统方法:将自己的QQ用户名和密码,告诉“人人网”或“云冲印”等第三方服务提供者,后者就可以读取用户的相关信息,进行登陆或获取资源。这样的做法有以下几个严重的弊端。

弊端

  • “第三方服务提供者”为了后续的服务,会保存用户的密码,这样很不安全。
  • “第三方”拥有了获取用户储存在QQ或Google(资源提供方)所有资料的权力,用户和资源提供方无法限制“第三方”获得授权的范围和有效期。
  • 用户只有修改密码,才能收回赋予“第三方”的权力。但是这样做,会使得其他所有获得用户授权的其他第三方服务全部失效。
  • 只要有一个第三方被破解,就会导致用户密码泄漏,进而泄露用户的所有数据。

OAuth协议就是为了解决上面这些问题而诞生的。

基本概念

名词定义

  • Open Authorization Protocol:开放授权协议。
  • Client:第三方服务提供者(第三方),又称“客户端”(client)。
  • Resource Owner:资源所有者,本文中又称“用户”(user)。
  • Authorization server:认证服务器,即服务提供商专门用来处理认证的服务器。
  • Resource server:资源服务器,即服务提供商存放用户生成的资源的服务器。它与认证服务器统称为:服务提供方。(逻辑上的区分,物理上可能是同一个服务器)
  • User Agent:用户代理,即浏览器。

OAuth基本思路

  • OAuth在"客户端"与"服务提供商"之间,设置了一个授权层(authorization layer)。“客户端"不能直接登录"服务提供商”,只能登录授权层,以此将用户与"客户端"区分开来。"客户端"登录授权层所用的令牌(token),与用户的密码不同。用户可以在授权认证时,指定授权层令牌的权限范围和有效期。
  • "客户端"登录授权层以后,"服务提供商"根据令牌的权限范围和有效期,向"客户端"开放用户储存的资料。

OAuth2.0基本流程

  • A: 用户打开客户端以后,客户端要求用户给予授权。
  • B: 用户同意给予客户端授权。
  • C: 客户端使用上一步获得的授权,向认证服务器申请令牌。
  • D: 认证服务器对客户端进行认证以后,确认无误,同意发放令牌。
  • E: 客户端使用令牌,向资源服务器申请获取资源。
  • F: 资源服务器确认令牌无误,同意向客户端开放资源。
    在这里插入图片描述
    来源:RFC 6749

OAuth2.0多种授权模式

在开放授权中,第三方应用(Client)可能是一个Web站点,也可能是在浏览器中运行的一段JavaScript代码,还可能是安装在本地的一个应用程序。为了支持这些不同类型的第三方应用,提出了多种授权类型。

  • 授权码模式(authorization code):流程最完整,使用最广泛,多见于第三方应用(Client)是Web站点。(QQ OAuth认证的 server-side模式)
  • 简化模式(implicit grant type):多用于在浏览器中运行的JavaScript等前端代码。(QQ OAuth认证的 client-side模式)
  • 密码模式(resource owner password credentials):用户向客户端提供自己的用户名和密码,类似传统方法。
  • 客户端模式(client credentials grant):客户端以自己的名义,而不是以用户的名义,向“授权服务方”进行认证。

本文重点解释授权码模式,代码实现也基于授权码模式。

授权码模式

  • 授权码模式(authorization code):是功能最完整、流程最严密的授权模式。它的特点就是通过客户端的后台服务器,与"认证服务提供商"的认证服务器进行互动。

步骤流程

  • A:用户访问第三方,后者将前者导向认证服务器。
  • B:用户选择是否给予第三方授权。
  • C:假设用户给予授权,认证服务器将用户导向第三方事先指定的"重定向URI"(redirection URI),同时附上一个授权码(authorization code)。
  • D:第三方收到授权码,附上早先的"重定向URI",向认证服务器申请令牌。(服务器后台完成)
  • E:认证服务器核对了授权码和重定向URI,确认无误后,向第三方发送访问令牌(access token)和更新令牌(refresh token)。

在这里插入图片描述
来源:理解OAuth 2.0 - 阮一峰

步骤参数细节

A步骤:客户端申请认证的URI
  • response_type:表示授权类型,必选项,此处的值固定为"code"
  • client_id:表示客户端的ID,必选项
  • redirect_uri:表示重定向URI,可选项
  • scope:表示申请的权限范围,可选项
  • state:表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值。
C步骤:服务器回应客户端的URI
  • code:表示授权码,必选项。该码的有效期应该很短,通常设为10分钟,客户端只能使用该码一次,否则会被授权服务器拒绝。该码与客户端ID和重定向URI,是一一对应关系。
  • state:如果客户端的请求中包含这个参数,认证服务器的回应也必须一模一样包含这个参数。
D步骤:客户端向认证服务器申请令牌的HTTP请求
  • grant_type:表示使用的授权模式,必选项,此处的值固定为"authorization_code"。
  • code:表示上一步获得的授权码,必选项。
  • redirect_uri:表示重定向URI,必选项,且必须与A步骤中的该参数值保持一致。
  • client_id:表示客户端ID,必选项。
  • client_secret:表示客户端密匙,可选项。
E步骤:两种类型的Token
  • Bearer Token:OAuth推荐token类型,生产环境中应该使用这种token。
  • Mac Token:不常采用。
  • 参考资料:OAuth 2.0: Bearer Token Usage

代码实现(OAuth2.0第三方Server和认证Server搭建)

具体流程

  • A:用户登录第三方网址,后者引导用户到认证服务器。
  • B:在认证服务器,用户“登录并同意授权”。
  • C:认证服务器跳转到第三方指定网址,并给予授权码。
  • D:在后台,第三方使用授权码向认证服务器兑换 access token。
  • E:在后台,第三方使用 access token 从资源服务器获取对应资源,或 使用refresh token更新 access token。

数据库关系

本示例,只有认证服务方有数据库

  • User:用户表
    • username: 用户名
    • password: 密码
    • info: 信息
  • Client:第三方表
    • 第三方id: client_name
    • 第三方密匙: client_secret
  • ClientUser:第三方与用户的授权关系表
  • AuthCode:授权码表,可用redis替代
    • code: 授权码
    • ClientUser.id: 授权关系id
    • redirect_uri: 第三方指定的跳转链接
    • expires_in: 有效时间短
    • used: 是否使用过,只能使用一次,因为容易暴露
  • AccessToken:
    • token: 访问令牌,此处使用uuid
    • ClientUser.id: 授权关系id
    • expires_in: 有效时间
  • RefreshToken:更新令牌,用来更新访问令牌
    • token: 更新令牌
    • AccessToken.id: 访问令牌的id
    • expires_in: 有效时间较长
  • Scope:授权访问范围分级

关键点

  • C步骤,授权码必须与跳转链接、第三方id一一对应。且需跳转到 第三方指定链接。
  • D步骤,兑换 access token 时,必须用client secret验证,因为 授权码容易在前台暴露,client secret在后台不易暴露。
  • 授权码的有效期必须很短,因为生成频繁,可以利用redis的超时设置特性。

项目代码

如需代码,请联系本人

参考资料

猜你喜欢

转载自blog.csdn.net/weixin_42359693/article/details/85068410