大家好,我是橘长,昨天分享了 「 令牌机制 」,大家可以自行回顾一下 OAuth 2.0 的核心是什么,令牌机制是什么、如何使用、开源组件等。
今天我们开始落地写代码,基于橘长之前接入过农业银行的授权,今天首先作为第三方服务来和大家分享「 手把手接入 OAuth 2.0 授权服务 」。
一、业务背景
近期团队帮银行做了一个互动营销活动,活动入口在行方的 App 上,当用户在行方 App 点击活动 banner 页跳转活动的时候参与。
在进活动之前作为业务方自然需要知道参与活动的人是谁,如何给它构建登录态。
这就是为什么橘长这边需要接入 行方 OAuth 2.0 组件的原因,本质就是获取 客户信息,回到活动业务形成登录态,进而可以参与活动。
使用的是 OAuth 2.0 中最完备的 授权许可机制 的这种接入方式,服务端发起型授权,为了方便展示,大部分采用了硬编码。
二、作为第三方软件需要做什么
1、静态注册
也可以称之为备案(注册信息) ,需要在 行方 的开放平台的管理态申请 OAuth 2.0 接入客户端,对于行方来说,确保第三方软件是可信的。
准备信息:第三方应用服务端 ip 地址、第三方应用回调通知地址、申请权限等。
1 | ini复制代码String ip = "xxx.xx.xx.xx"; |
等授权服务的后台人员处理之后会颁发相关配置,用来表示唯一标识 第三方软件 的相关配置。
如下是一个简单示例模板:
1 | ini复制代码String appid = "appid_001"; |
2、引导用户授权
1)第一步:用户访问第三方软件,判断凭据
如果没有携带 JWT 或 已过期,服务端响应 Http 状态码 401 给前端,前端会请求服务端的发起授权接口。
1 | ruby复制代码// 比方说访问活动首页接口 |
2)第二步:客户端收到 401,请求授权接口
第三方软件后端会和授权服务交互,获取授权页地址,然后 302 跳转引导用户到授权页。
- controller 层
1 | less复制代码@Slf4j |
日志打印:
1 | perl复制代码xxxx [发起授权] 构建的授权地址为:[http://xxx/oauth/authorize?client_id=xxx&redirect_uri=http%3A%2F%2Fxxx%2F%2Foauth%2Flogin%2Fsuccess&state=d8cb3943cd3a45818711fa4f6a8820e9&scope=custid%2Cphone&response_type=code] |
- service 实现
1 | typescript复制代码@Override |
service 这层根据标准 OAuth 2.0 的要求更合理做法是 请求授权服务获取,这里授权服务设计有点不合理,后续调整。
3)第三步:授权服务回调通知,分发临时授权码
1 | arduino复制代码@RequestMapping("/login/success") |
日志打印:
1 | css复制代码xxxx [oauth 服务]-回调,接收到数据为:code:[xxx], state:[xxx] |
4)第四步:第三方服务通过 code 换取 token
1 | typescript复制代码private String getToken(final String clientId, |
打印日志:
1 | css复制代码xxxx [授权服务 code 获取 token] 结果为:[{"access_token":"xxx","expires_in":7200}] |
5)第五步:拿到 凭据,访问业务接口
当用授权码换取到 凭据 之后,通过凭据去获取用户在受保护资源服务的数据,比方说获取用户信息。
1 | ini复制代码public String getUserInfoFromOAuthServer(String token) { |
打印日志:
1 | css复制代码xxxx [从授权服务换取用户信息] 解密出来的用户信息为:[{"openid":"xxx","headImg":"xxx"}] |
6)第六步:用户信息入库,分发业务 code 给前端
拿到用户信息,写入活动服务的业务表中,然后通知前端说授权完成啦,颁发活动业务的 临时码(code)给客户端,便于客户端来换取活动业务的 JWT。
- 用户信息入库
1 | arduino复制代码public RedirectView loginSuccess(String ...) { |
- 服务端通知前端
1 | typescript复制代码private RedirectView redirectFrontEndUrl(final String sceneId, |
7)第七步:客户端通过 code 换取 业务 jwt
1 | typescript复制代码/** |
获取到的 JWT:
1 | ini复制代码{ |
三、总结
今天橘长一步一步带着大家写代码手把手接入 OAuth 2.0 授权服务,大家需要记住几点:
1、关注 授权服务 的官方文档,开放平台接入文档是一个很重要的凭据。
2、第三方软件接入授权尽量采用 服务端发起型 授权,使用 授权码许可机制,因为这更安全、更完备。
3、强烈建议你手把手撸一遍,OAuth 2.0 接入的代码很考验基本功和代码风格,其中用到了 Redis 缓存、Hutool 工具去发起 Http 请求等。
下一篇橘长将给大家带来「 手把手搭建 OAuth 2.0 授权服务 」的解读,感谢你的关注,如果你觉得有所收益,欢迎点赞、转发、评论,感谢认可!
有任何疑问也可以添加我的好友(wx:mbandtr),欢迎沟通。
本文转载自: 掘金