讲讲Oauth的授权认证

前言

前段时间一直在忙SSO统一登录的事情,也算是对登录这块有了点新得体会,比之前为了应付面试死记硬背的情况好了一些,今天就先小讲一下OAUTH机制

先说说情景:你是一个初出茅庐的写代码爱好者,StackOverflow是你常上的网站。有一天你想回答一个问题,但你突然发现长久以来都是在看回帖,连账号都没有注册。于是你点击了 Log in 按钮。

你对这个问题颇有兴致,恨不得立即写下回答,但你一想到漫长的注册流程(思考密码、点这里点那里、打开邮箱等待确认邮件···)

正当你因为注册账号而预感到恼火的时候,你看到了它旁边的熟悉的Gitub的logo:章鱼猫。互联网冲浪多年的你下意识的点了上去,因为你知道,它的作用就是用Github的账号授权给StackOverflow,直接登录,轻松加愉快。(国内往往因为政策原因要继续让你用手机注册,所以体验会差些)

所以,你有没有想过它的原理是是什么呢?

oauth简单原理

oauth全称Open Authorization(开放授权),是关于授权的开放网络标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源。而这些“私密”资源其实也算不得什么特别隐私的,只是你的用户名、你的基础资料,它们可以标识你在互联网上的身份。而更加隐私的资料,是不能获取到的。

(你问非隐私资源?我想如果有的话就直接跨域共享了吧)

图片

图源:RFC 6749

(A)客户端向资源拥有用户申请资源授权

(B)用户同意给予客户端授权,并返回授权凭证。

(C)客户端使用上一步获得的授权凭证,向认证服务器申请令牌。

(D)认证服务器对客户端进行认证以后,确认无误,同意发放令牌。

(E)客户端使用令牌,向资源服务器申请获取资源。

(F)资源服务器确认令牌无误,同意向客户端开放资源。

资源服务器未必就和认证服务器完全分开,有可能只是不同路由的区别。

以微信登录授权为例

  1. 获取授权凭证-授权码authorization_code(A、B步)

第三方应用(比如知乎)想要获取你的基本信息,它显示了登录页面,下面有微信登录选项。你点击了它,知乎调用了微信开放平台提供的 SDK 进行授权登录请求接入,在终端本地拉起微信进入授权页面,微信用户确认后微信再拉起第三方应用,并附带上临时授权码(authorization_code)

  1. 第三方应用通过拿到的临时授权码、加上appId(第三方应用登记在微信平台的ID)、secret(appID 对应的密码)请求微信平台,获取到微信授予的access_token(C、D步)

access_token是存储在客户端的(当然这块也有可能有安全性问题,这里就不讨论了)

  1. 请求中携带access_token作为凭证请求资源(E、F步)

由于 access_token 有效期较短,当 access_token 超时后,可以使用 refresh_token 进行刷新,也可以停掉access_token的权限

仔细说说

为啥要把登录体系做的这么别扭且复杂呢?为了回答这个问题,我们可以开几个if线:

  • 如果我直接将微信用户名密码告诉第三方应用:

第三方应用为了后续持续服务,保存用户的密码,而当第三方应用逐渐变多,那么只要有一个恶意应用拿到了你的密码(或者攻破了一个应用),全体GG,你互联网上的所有账号被洗劫一空

  • 如果只有临时授权码,没有appid和secret就可以获取资源:

恶意第三方应用直接拿着授权码(或者盗取来的授权码)请求你的资源,再次GG

  • 如果微信服务器无法ban掉你的access_token:

等同于你家里的钥匙托付给了邻居,但是邻居不还了

OAUTH是一个很高级的资源授权方式,“认证层”的出现既保证了安全性又能灵活的访问资源。

授权类型

OAuth 2.0 列举了四种授权类型,分别用于不同的场景:

  • Authorization Code(授权码 code):服务器与客户端配合使用。
  • Implicit(隐式 token):用于移动应用程序或 Web 应用程序(在用户设备上运行的应用程序)。
  • Resource Owner Password Credentials(资源所有者密码凭证 password):资源所有者和客户端之间具有高度信任时(例如,客户端是设备的操作系统的一部分,或者是一个高度特权应用程序),以及当其他授权许可类型(例如授权码)不可用时被使用。
  • Client Credentials(客户端证书 client_credentials):当客户端代表自己表演(客户端也是资源所有者)或者基于与授权服务器事先商定的授权请求对受保护资源的访问权限时,客户端凭据被用作为授权许可。

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!