举一个电商的场景,你估计更有感觉。假如你是一个卖家,在京东商城开了一个店铺,日常运营中你要将订单打印出来以便给用户发货。但打印这事儿也挺繁琐的,之前你总是手工操作,后来发现有个叫“小兔”的第三方软件,它可以帮你高效率地处理这事。
但你想想,小兔是怎么访问到这些订单数据的呢?其实是这样,京东商城提供了开放平台,小兔通过京东商家开放平台的 API 就能访问到用户的订单数据。
只要你在软件里点击同意,小兔就可以拿到一个访问令牌,通过访问令牌来获取到你的订单数据帮你干活儿了。你看,这里也是有一次授权。你要是不同意,平台肯定不敢把这些数据给到第三方软件。
OAuth 2.0 这种授权协议,就是保证第三方(软件)只有在获得授权之后,才可以进一步访问授权者的数据。因此,我们常常还会听到一种说法,OAuth 2.0 是一种安全协议。现在你知道了,这种说法也是正确的。
现在访问授权者的数据主要是通过 Web API,所以凡是要保护这种对外的 API 时,都需要这样授权的方式。而 OAuth 2.0 的这种颁发访问令牌的机制,是再合适不过的方法了。同时,这样的 Web API 还在持续增加,所以 OAuth 2.0 是目前 Web 上重要的安全手段之一了。
图中的流程只是授权码的方式
1.access_token不显示在浏览器是因为安全原因
2.浏览器直接获取调用授权带着回调,然后授权服务器把access_token直接返回给服务器行不行?
首先access_token需要secret,客户端不能存储,所以请求access_token必须通过服务端。如果取消授权码模式,客户端需要更复杂的签名加密方式去把secret传递过去获取access_token。
去访问一个网站,如果登录的话,需要注册,填一堆信息,用户名密码啥的,通常密码是前端加盐、哈希(md5,sha1等)然后再发给后端,后端存储起来,不能直接存储明文。然后再跳转到登录页面,输入用户名和密码,后端验证用户名和密码,如果成功了返回一个session id,然后前端就可以结合cookie使用。
问题:
1.安全性,需要对密码的加密有一个万全的应对之策
2.维护麻烦,用户用起来也麻烦
后来yelp试图解决这些问题,如下图所示
想用什么登录就选中,但是得需要对应的用户和密码,然后yelp会用密码去google拉取你的相关信息。
问题:
1.安全性,虽然yelp承诺了不保存用户google的密码,但是可能是小公司,没有信用累积(谁知道背着用户有没有在后台做什么)
为了解决这些问题,oauth2.0授权登录出现了
上个流程换用oauth2.0的流程就变成下面的了
小公司不值得信任,但是我信任google,所以yelp与google建立联系
用户点击使用google登录,然后跳转到google的登录页面,输入自己google的账号和密码,然后弹出一个框,是否同意yelp访问你的个人信息和通讯录信息
如果你点否,那么yelp将会什么都不做,可能也无法登录
如果点击是,会回调到yelp的某个页面,然后yelp的后台会去访问google你的信息和页面,通过某种介质
这个流程总结为我授权yelp去google可以拿到我的个人信息和通讯录
Resource owner: 资源的拥有者, 即想使用google登录yelp的用户
Client: 客户端 即yelp app
Authorization server:授权服务,即上述流程中的account.google.com,在这里你登录了google,并且同意了授权
Resource server:资源服务,即上述流程中的contacts.google.com,存储你相关信息的服务
Authorization grant(这个好像是scops):同时赋予某种权限,图中赋予了个人信息和通讯录的权限
Redirect URI: 回调URL,即上述流程中,授权成功后,跳转回的那个callback url
Access Token : 去访问Resource server的令牌,即上述流程中yelp后台通过这个可以去google访问,获取到你同意的那些信息(个人信息,通讯录)
用户使用google授权登录,yelp跳转到google的Authorization server, 通过下图的uri, 指定回调url,response type:code授权码方式,以及想要获取哪些授权,这里是profile 和 contacts。
然后如果没有登录,用户登录,成功后,跳转询问用户是否同意上述授权
如果同意了,又调回到我们指定的回调url,并且带着授权码,如下图
第一个uri是用户点否后,回调的uri
第二个uri是用户点击是后,回调的uri
拿到这个uri后, client 即会访问这个uri,请求到yelp的后端进行应该的操作
假设用户同意授权,即yelp后端会用授权码 去换取token, 通过token在yelp后端再拿到用户的信息
多了授权码这一步,就是为了避免access_token在前端暴露, 加强了安全性
上图就是前端拿到uri后,访问后端,后端要进行的操作,即用授权码和你再google注册的client_id,client_secret 来交换access_token。 ps:回调url也是在google注册的时候填写的。
上图即拿code交换access_token的响应body ps:少了refresh_token, 这个东西的过期时间会更长,一般access_token过期后,不用再走授权码的流程,只需要拿refresh_token去换取新的access_token和refresh_token即可。
问题:
oauth2.0是授权不是认证,所以用它拿来做用户认证是不正确的
而且oauth2.0不是一个标准的协议,各家实现都有差异。
为了解决这些问题,OpenID Connect的概念随即被提出
如图所示,oauth2.0是授权authorization ,OpenID Connect是认证 authentication
OpenID Connect在oauth2.0的基础上封装了一层,支持了用户认证。 也同样支持授权码方式,也oauth2.0不同的时返回了ID Token,用来做认证。下面看一下OpenID Connect的授权码流程
1.Scope:必须指定openid
2.ID token与 access_token一起返回
这2点是与oauth2.0不同的地方,其他的都类似。
多了个id_token, 一般是用jwt协议实现的,(jwt是啥,可以看我另一篇文章) 如下所示
获取用户信息
撤销token