架构:
接口设计:获取code的接口+获取access_token+获取资源服务器
页面设计:登录页->授权页 (需要打开app并判断是否已登录,未登录先登录,已登录则调到授权页(可静默授权直接返回到 redirect_uri))
①建立一个开放平台用于开发者注册获取app key、app secret,然后app key与app secret会将数据存储到认证服务器 #此处需建立一个数据表(开发者信息表-developer 表、authorzation表)
开发者信息表(developer):id、app_key、app_secret、redirect_uri(授权后的回调地址)、code(用于记录授权码)、access_token、username、desc、created_at、updated_at
认证表(authorization):id、developer_id(索引对应的开发者信息)、user_id(用户id索引)、code、access_token、expires_in、created_at、updated_at #可合并到用户表注:开放平台返回时可能会存在第三方应用的正式网址,但是这样可能会存在本地验证测试问题
②在客户端(即向我们开放平台申请用户信息的用户的站点)向认证服务器发起 类似以下请求
GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz # 整个get请求需要强正则验证顺序
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1 # redirect_uri写在开放文档中,用于认证完回调的的地址
Host: server.example.com # 认证服务器
请求到认证服务器,先判断是否已登录(未登录跳转到登录页面),反之跳转到用户授权页面(建议静默授权无需用户点击确认),授权后根据redirect_uri返回授权码(相应的authorzation认证表更新授权码code及updated_at)。
注: 在客户端使用session标记是否授权状态,决定用户是否登录后进而判断验证client_id返回授权码code
响应:
HTTP/1.1 302 Found
Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&state=xyz
注:以上是请求后返回的响应,state用于防止csrf攻击
③上一步获取了授权码code(get可获取),由于这里是经过用户授权通过后获取到的code,所以是安全的,发起请求如下:
grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb
这里验证code、redirect_uri,然后更新authorization中 access_token、updated_at
??问题??:授权码要绑定用户吗?每一个用户对应一个授权码? 目前情况是分理处一个认证表(authorization)用于单独为每个用户绑定,最好就是将该表合并到用户表
响应:
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store # 不得缓存
Pragma: no-cache
{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":"example",
"expires_in":3600,
"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
"example_parameter":"example_value"
}
④获取access_token后即可获取指定资源(过期重新refresh_token即可)
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic 2YotnFZFEjr1zCsicMWpAA
Content-Type: application/x-www-form-urlencoded