本文旨在阐明 OAuth2.0 体系中第三方软件和受保护资源服务的职责。
1 构建第三方软件应用
若基于公众号开放平台构建一个xx文章排版软件的轻应用,需要先到公众号开放平台申请注册成为开发者,再创建个应用就可以开始开发了。
1.1 开发过程的关键节点
1.1.1 注册信息
xx软件必须先有身份,才能参与 OAuth 2.0 流程。即xx需要拥有 app_id 和 app_serect、自己的回调地址 redirect_uri、申请权限等信息。
这称为静态注册,即xx开发人员提前登录到公众号开放平台手动注册,以便后续使用这些注册的相关信息来请求访问令牌。
1.1.2 引导授权
当用户要使用三方软件操作在受保护资源上的数据,就需要三方软件引导
授权。
大家也很熟悉,我要使用xx来对我公众号里的文章排版时,我首先访问的
一定是xx软件,而不是授权服务&受保护资源服务。
但xx需要我的授权,只有授权服务才能允许我的操作。所以xx需要将我引导至授权服务
String oauthUrl = "http://localhost:8081/Oauth?reqType=oauth"; response.sendRedirect(toOauthUrl);
让用户为三方软件授权,得到授权后,三方软件才可以代表用户去访问数据。即xx获得授权后,就能代表我去排版文章。
1.1.3 使用访问令牌
第三方软件的最终目的:拿到令牌后去使用令牌。目前OAuth 2.0 令牌只支bearer 类型的令牌,即任意字符串格式的令牌。
官方规范给出的使用访问令牌请求的方式,有三种
Form-Encoded Body Parameter(表单参数)
URI Query Parameter(URI 查询参数)
Authorization Request Header Field(授权请求头部字段)
如何选型?
- OAuth 2.0 官方建议,系统在接入 OAuth 2.0 前信息传递的请求载体是 JSON,若继续采用表单参数提交,令牌就无法加入。
- 若采用参数传递,URI 会被整体复制,安全性最差。
- 请求头部字段无上述顾虑,因此被官方推荐。
但小小推荐采用表单提交 POST 方式提交令牌,类似如下代码所示。毕竟官方建议指的是在接入 OAuth 2.0 前,若你已采用 JSON 请求体条件下,才不建议使用表单提交。倘若一开始三方软件和平台都一致采用表单提交,就没问题了。因为表单提交在保证安全传输同时,无需处理 Authorization 头部信息。
String protectedURl="http://localhost:8081/ProtectedServlet"; Map<String, String> paramsMap = new HashMap<String, String(); paramsMap.put("app_id","APPID_XX); paramsMap.put("app_secret","APPSECRET_XX"); paramsMap.put("token",accessToken); String result = HttpURLClient.doPost(protectedURl,HttpURLClient.mapToStr(paramsMap));
1.1.4 使用刷新令牌
解决痛点
若访问令牌过期了,xx总不能立马提示让我这客户重新授权吧!
就需要刷新令牌。刷新令牌需注意何时决定使用刷新令牌。
在xx排版软件收到访问令牌同时,也会收到访问令牌的过期时间 expires_in。优秀的三方软件应将 expires_in 值保存并定时检测;若发现 expires_in 即将过期,则需要利用 refresh_token 重新请求授权服务,获取新的有效访问令牌。
除定时检测可提前发现访问令牌是否快过期,还有“现场”发现。即比如xx访问我的公众号文章时,突然收到一个访问令牌失效的响应,此时xx立即使用 refresh_token 请求一个访问令牌,以便继续代表我使用我的这些文章数据。
可得:
- 定时检测方案需开发定时任务
- “现场”发现,就没这额外工作咯
还是推荐定时检测,因可以带来“提前量”,以便让更好掌握主动权。
刷新令牌是一次性的,使用后就失效,但它的有效期会比访问令牌长。
若刷新令牌也过期呢?
需将刷新令牌和访问令牌都放弃,几乎回到系统初始状态,只能让用户重授权。


