加密与授权 Oauth2.0

加密算法

对称加密

加密和解密使用同样规则(简称"密钥",这被称为"对称加密算法"
在这里插入图片描述
缺点:密钥的传递和保存变得尤为重要,一旦密钥丢失,则出现数据安全问题。然而加密方和解密方都有可能丢失密钥。

非对称加密

加密和解密可以使用不同的规则,只要这两种规则之间存在某种对应关系即可,这样就避免了直接传递密钥。

  • 乙方生成公钥和私钥,公钥对外公开,私钥则自己保管
  • 甲方从乙方那获得公钥,用公钥加密信息传递到乙方
  • 乙方使用自己的私钥解密甲方发送过来的加密信息
    在这里插入图片描述
    优势:解密的乙方一方保管私钥,降低了私钥丢失的风险。而对称加密则需要加密解密方都防止丢失密钥,一旦任何一方丢失密钥,则不安全。
    1977年,三位数学家Rivest、Shamir 和 Adleman 设计了一种算法,可以实现非对称加密。这种算法用他们三个人的名字命名,叫做RSA算法。从那时直到现在,RSA算法一直是最广为使用的"非对称加密算法"。

RSA算法的原理: 互质关系,欧拉函数,欧拉定理,模反元素

授权机制

在这里插入图片描述

密码授权

上图是豆瓣web应用的登录页面,它允许用户使用第三方应用账户进行登录。如果我们使用传统的密码授权登录,则需要将自己的第三方账户用户名和密码告诉豆瓣网,然后豆瓣应用拿着用户的第三方信息去第三方应用进行验证,如果信息存在且正确,则第三方应用授权给豆瓣网进行登录。

安全问题:

  1. 豆瓣网为何后续的操作授权会保存用户的第三方应用信息(用户名,密码…),第三方应用肯定也不希望公布自己用户信息给其他应用
  2. 一旦豆瓣网之类的应用被破解,则保存的第三方应用数据也可能跟着被泄露
  3. 豆瓣网拿着拥有的用户信息可以获得用户在第三方应用的所有权限
  4. 用户若想要收回豆瓣网对于第三方应用的权限则需要修改密码,这回导致所有的使用第三方应用登录的应用失去授权

OAuth2.0

名词解释:

  1. Third-party application:第三方应用程序,本文中又称"客户端"(client),即上一节例子中的"豆瓣"。
  2. HTTP service:HTTP服务提供商,本文中简称"服务提供商",即上一节例子中的Wechat。
  3. Resource Owner:资源所有者,本文中又称"用户"(user)。
  4. User Agent:用户代理,本文中就是指浏览器。
  5. Authorization server:认证服务器,即服务提供商专门用来处理认证的服务器。
  6. Resource server:资源服务器,即服务提供商存放用户生成的资源的服务器。它与认证服务器,可以是同一台服务器,也可以是不同的服务器。

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

"客户端"登录授权层以后,"服务提供商"根据令牌的权限范围和有效期,向"客户端"开放用户储存的资料。
在这里插入图片描述

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

  • 授权码模式(authorization code)
  • 简化模式(implicit)
  • 密码模式(resource owner password credentials)
    客户端模式(client credentials)

注意,不管哪一种授权方式,第三方应用申请令牌之前,都必须先到系统备案,说明自己的身份,然后会拿到两个身份识别码:客户端 ID(client ID)和客户端密钥(client secret)。这是为了防止令牌被滥用,没有备案过的第三方应用,是不会拿到令牌的。

授权码(authorization-code)

授权码(authorization code)方式,指的是第三方应用先申请一个授权码,然后再用该码获取令牌。
这种方式是最常用的流程,安全性也最高,它适用于那些有后端的 Web 应用。授权码通过前端传送,令牌则是储存在后端,而且所有与资源服务器的通信都在后端完成。这样的前后端分离,可以避免令牌泄漏。

第一步, 豆瓣网站提供一个链接,用户点击后就会跳转到 WeChat 网站,授权用户数据给 豆瓣 网站使用。下面就是 豆瓣 网站跳转 WeChat 网站的一个示意链接。

https://open.weixin.qq.com/connect/qrconnect
?appid=wxd9c1c6bbd5d59980
&redirect_uri=https%3A%2F%2Fwww.douban.com%2Faccounts%2Fconnect%2Fwechat%2Fcallback
&response_type=code
&scope=snsapi_login
&state=yX4Mo6vQG1c%2523douban-web%2523https%253A%2F%2Fwww.douban.com%2F

上面 URL 中,response_type参数表示要求返回授权码(code),app_id参数让 WeChat 知道是谁在请求,redirect_uri参数是 WeChat接受或拒绝请求后的跳转网址,scope参数表示要求的授权范围(这里是login),state参数是关于状态信息
在这里插入图片描述

第二步,用户跳转后,WeChat网站会要求用户登录,然后询问是否同意给予 豆瓣 网站授权。用户表示同意,这时 WeChat 网站就会跳回redirect_uri参数指定的网址。跳转时,会传回一个授权码,就像下面这样。

https://www.douban.com/accounts/connect/wechat/callback
?code=08127W0w3dbMKX2wgL3w3xeZtQ327W0g
&state=yX4Mo6vQG1c#douban-web#https://www.douban.com/

在这里插入图片描述

第三步,豆瓣 网站拿到授权码以后,就可以在后端,向 WeChat 网站请求令牌。

https://www.douban.com//oauth/token?
appid=wxd9c1c6bbd5d59980
&client_secret=CLIENT_SECRET
&grant_type=authorization_code&
&code=08127W0w3dbMKX2wgL3w3xeZtQ327W0g(这是我们刚从wechat拿到的授权码)
&redirect_uri=CALLBACK_URL

上面 URL 中,appid参数和client_secret参数用来让 WeChat 确认 豆瓣网 的身份(client_secret参数是保密的,因此只能在后端发请求),grant_type参数的值是AUTHORIZATION_CODE,表示采用的授权方式是授权码,code参数是上一步拿到的授权码,redirect_uri参数是令牌颁发后的回调网址。
在这里插入图片描述

第四步,WeChat 网站收到请求以后,就会颁发令牌。具体做法是向redirect_uri指定的网址,发送一段 JSON 数据。

{    
  "access_token":"ACCESS_TOKEN",
  "token_type":"bearer",
  "expires_in":2592000,   
  "refresh_token":"REFRESH_TOKEN",
  "scope":"read",
  "uid":100101,
  "info":{...}
}

上面 JSON 数据中,access_token字段就是令牌,豆瓣 网站在后端拿到了。后面便可以根据此Token内部包含的权限,去读取一些WeChat内授权的资源。

在这里插入图片描述

隐藏式(implicit)

有些 Web 应用是纯前端应用 (例如一些浏览器插件啊…),没有后端。这时就不能用上面的方式了,必须将令牌储存在前端。RFC 6749 就规定了第二种方式,允许直接向前端颁发令牌。这种方式没有授权码这个中间步骤,所以称为(授权码)“隐藏式”(implicit)。

第一步,插件 网站提供一个链接,要求用户跳转到 WeChat 网站,授权用户数据给 插件 网站使用。

https://open.weixin.qq.com/connect/qrconnect
?appid=wxd9c1c6bbd5d59980
&redirect_uri=plugin_website_url
&response_type=token
&scope=snsapi_login

上面 URL 中,response_type参数为token,表示要求直接返回令牌。

第二步,用户跳转到 WeChat 网站,登录后同意给予 插件 网站授权。这时,WeChat 网站就会跳回redirect_uri参数指定的跳转网址,并且把令牌作为 URL 参数,传给 插件 网站。

https://plugin.com/callback#token=ACCESS_TOKEN

上面 URL 中,token参数就是令牌,插件 网站因此直接在前端拿到令牌。

注意,令牌的位置是 URL 锚点(fragment,#token=ACCESS_TOKEN),而不是查询字符串(querystring,?token=ACCESS_TOKEN),这是因为 OAuth 2.0 允许跳转网址是 HTTP 协议,因此存在"中间人攻击"的风险,而浏览器跳转时,锚点不会发到服务器,就减少了泄漏令牌的风险。

在这里插入图片描述

密码式(password)

如果你高度信任某个应用,RFC 6749 也允许用户把用户名和密码,直接告诉该应用。该应用就使用你的密码,申请令牌,这种方式称为"密码式"(password)。

第一步,A 网站要求用户提供 WeChat 网站的用户名和密码。拿到以后,A 就直接向 WeChat 请求令牌。

https://open.weixin.qq.com/connect/token
?appid=wxd9c1c6bbd5d59980
&grant_type=password
&username=USERNAME
&password=PASSWORD

上面 URL 中,grant_type参数是授权方式,这里的password表示"密码式",username和password是 B 的用户名和密码。

第二步,WeChat 网站验证身份通过后,直接给出令牌。注意,这时不需要跳转,而是把令牌放在 JSON 数据里面,作为 HTTP 回应,A 因此拿到令牌。
这种方式需要用户给出自己的用户名/密码,显然风险很大,因此只适用于其他授权方式都无法采用的情况,而且必须是用户高度信任的应用。

客户端凭证(client credentials)

凭证式(client credentials),适用于没有前端的命令行应用,即在命令行下请求令牌。

第一步,A 应用在命令行向 WeChat 发出请求。

https://open.weixin.qq.com/connect/token 
?grant_type=client_credentials&
&client_id=CLIENT_ID&
&client_secret=CLIENT_SECRET

上面 URL 中,grant_type参数等于client_credentials表示采用凭证式,client_id和client_secret用来让 WeChat 确认 A 的身份。

第二步,WeChat 网站验证通过以后,直接返回令牌。

这种方式给出的令牌,是针对第三方应用的,而不是针对用户的,即有可能多个用户共享同一个令牌。

令牌的使用

A 网站拿到令牌以后,就可以向 WeChat 网站的 API 请求数据了。

此时,每个发到 API 的请求,都必须带有令牌。具体做法是在请求的头信息,加上一个Authorization字段,令牌就放在这个字段里面。

在这里插入图片描述

更新令牌

令牌的有效期到了,如果让用户重新走一遍上面的流程,再申请一个新的令牌,很可能体验不好,而且也没有必要。OAuth 2.0 允许用户自动更新令牌。

具体方法是,授权 网站颁发令牌的时候,一次性颁发两个令牌,一个用于获取数据,另一个用于获取新的令牌(refresh token 字段)。令牌到期前,用户使用 refresh token 发一个请求,去更新令牌。

https://open.weixin.qq.com/connect/token 
?grant_type=refresh_token
&client_id=CLIENT_ID
&client_secret=CLIENT_SECRET
&refresh_token=REFRESH_TOKEN

上面 URL 中,grant_type参数为refresh_token表示要求更新令牌,client_id参数和client_secret参数用于确认身份,refresh_token参数就是用于更新令牌的令牌。

授权 网站验证通过以后,就会颁发新的令牌。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值