记录值得记录下的事情

Oauth2.0

折腾的API接口有很多人使用,总觉得通过数据库管理ApiKey效率低下,应该聚合一个控制平台进行自助管理。参考了很多文章,最后决定使用Oauth2.0标准扩展API管理。

Oauth2.0

OAuth是一个关于授权(authorization)的开放网络标准,在全世界得到广泛应用,目前的版本是2.0版。OAuth2.0标准主要围绕三类应用:Web应用、基于客户端的应用、原生应用。

OAuth2.0专用名词:

  • Third-party application:第三方应用程序,又称"客户端"(client)。
  • HTTP service:HTTP服务提供商,本文中简称"服务提供商",即上一节例子中的Google。
  • Resource Owner:资源所有者,又称"用户"(user)。
  • User Agent:用户代理,本文中就是指浏览器。
  • Authorization server:认证服务器,即服务提供商专门用来处理认证的服务器。
  • Resource server:资源服务器,即服务提供商存放用户生成的资源的服务器。

OAuth2.0的运行流程如下图,摘自RFC6749。
运行流程

OAuth2.0授权前,第三方应用必须到平台上进行注册,注册过程中可能需要填写的内容有:应用类型,授权成功回调地址,以及其他平台需要的资料(应用名称、网址、介绍、LOGO图片等)。应用在Open开发者平台注册完成会得到一个应用client_id和一个client_secret,一般叫App_Key,密钥叫App_Secret,这两样东西作用跟用户名密码是一样的。

OAuth2.0中提到的授权方式有四种:授权码(Authorization Code)、隐式授权(Implicit Grant)、用户口令(Resource Owner Password Credentials)、应用口令(Client Credentials)。这四种方式最终的目的都是要获得Access Token,然后通过请求Resource服务器获取资源。

Authorization Code

授权码方式在很多地方都有用到,微博登陆,微信登陆等都是。

认证过程主要是跳转到Oauth2.0平台,认证后跳转回第三方应用平台,并通过callback的url中携带code、state、token_type等信息,然后第三方平台通过code获取到access_token,进而调用开放API获取到资源。第三方请求过程必须附带,response_type(回调类型:code,token),client_id(开发者appkey),redirect_uri(回调链接),state(防止csrf,authorization认证跳转后原样返回)。

第一步:跳转到Oauth2.0服务器:认证过程中会请求scope权限表,用户可以拒绝相应权限。
第二步:用户确认请求的权限,回调得到code。
第三步:第三方平台通过code得到access_token,然后通过API调用Resource服务器资源。

这个过程需要发送client_id,client_secret(App Secret),grant_type(’authorization_code’),code,redirect_uri给oauth2服务器获取access_token。

Implicit Grant

隐式授权流程(Implicit Grant)其实就是Authorization Code的一个简化版本,不是回调code,而是直接回调access_token给第三方开发者,response_type变为token,其他和Authorization Code一样。

例如:

domain.com/oauth2/lockdin/authorize?response_type=token&client_id=demoapp&redirect_uri=http%3A%2F%2Fdomain.com%2Foauth2%2Fclient%2Freceive_implicit_token&state=377edd18bd3070e4317889b0b3371c16

跳转后就得到了,如下链接:

domain.com/oauth2/client/receive_implicit_token#access_token=a845c2c81bc57613bbc5dee1fec173a3fbd0f474&expires_in

Client Credentials

应用授权(Client Credentials)主要用于第三方应用直接获取一些公开的数据,不需要用户跳转认证,也不需要获取用户的openid,因为都是一些公共的资源。

假设我的请求数据为:

{client_id: "testclient", client_secret: "testpass", grant_type: "client_credentials", scope: "userinfo cloud file node"}

Oauth2.0给我的回调数据:
{"access_token":"417206d0e162d743338c04da9f8eb72f99daff6b","expires_in":3600,"token_type":"Bearer","scope":"userinfo cloud file node"}

可以看到有了access_token,然后我就可以用access_token去找Resource服务器要资源了,这里限定了scope权限表,表的权限应该在open平台注册的时候就确定下来了。

Resource Owner Password Credentials

用户口令(Resource Owner Password Credentials)适合内部应用调用使用,比如两个平台A和B,那么就可以在Oauth2.0下通过Password Credentials模式实现A应用与B应用之间通信,还可以开放内部接口。

请求的数据格式是:

{grant_type: "password username:"user", password: "pass",client_id: ""testclient", client_secret: "testpass", scope: "userinfo cloud file node}

回调数据比Client Credentials多了一个refresh_token:

{"access_token":"8a478275f8d2d5ac767f94ef0684a1fc2883eb24", "expires_in":3600, "token_type":"Bearer", "scope":"userinfo cloud file node", "refresh_token":"69a5e7b995ed4376bd6dd58380bfe09b51137dcb"}

那么当access_token过期后,就可以通过refresh_token再次激活一个新的access_token,黑魔法,自己给自己开后门。

激活请求发送的数据为:

{grant_type: "refresh_token", username:"user", password: "pass", client_id: ""testclient", client_secret: "testpass", scope: "userinfo cloud file node}

返回还是一个新的access_token数据。

参考

标签: API, Oauth2

添加新评论