游戏世界
游戏攻略
网盘资源
有趣网站
游戏资讯
PS2游戏
PS3游戏
PS4游戏
PS5游戏
switch游戏
PC游戏
软件分享
编程指南
开发小册
Java开发
iOS开发
前端开发
JavaScript开发
Android开发
PHP开发
数据库
开发工具
Python开发
Kotlin开发
Ruby开发
.NET开发
服务器运维
开放平台
架构师
大数据
云计算
人工智能
开发语言
其它开发
spring6中文文档
springboot3中文文档
主机游戏
PS订阅游戏-美服
PS订阅游戏-港服
XGP PGP游戏
SteamDeck游戏
VR PSVR2游戏
3A游戏基地
PS3游戏
spring中文文档
spring6中文文档
springboot3中文文档
vlambda博客
学习文章列表
首页
架构师
vlambda
2022-03-17
头号作家丨基于OAuth2.0的HeyTap运动健康开放平台授权鉴权方案设计
栏目介绍
“头号作家”是由OPPO工程师们解读时下热门技术的专题栏目。在这里,你不仅能看到最新最火的动态趋势,更能与OPPO的优秀工程师们共同学习技术干货。
头号作家
■
Terry
■
热爱技术的后端开发一枚,喜欢分享,在微服务和DDD领域都有不错的实践。
01
背景
随着人们越来越关注自己和家人的运动健康,运动健康沉淀了大量高质量的用户数据。同时随着我们的运动智能设备使用的日益广泛,接入的外部渠道越来越多,迫切需要一套标准开放平台,方便各种设备接入和服务接入,加速健康的合作伙伴引入与落地。
02
行业常用授权鉴权方案
一般行业内通用的授权鉴权使用OAhth 2.0授权码的方式来实现。具体流程如下:
1.三方提供一个url,放在合适的位置,然后用户点击后调转到平台授权页。比如:
https://xxx.wanyol.com/open/v1/oauth/authorize? response_type=code& client_id=CLIENT_ID& redirect_uri=CALLBACK_URL& scope=read
其中response_type表示授权方式,code表示授权码,client_id是平台给三方的身份信息,用于标识是哪个三方,redirect_uri用户跳转回三方页面。scope标识请求的授权范围。
2.用户到了平台授权页后,需要用户登录平台账号,用户授权后服务端会生成授权码code,并通过redirect_uri返回。比如:
https:
//open.gotoxxx.com/callback?code=AUTHORIZATION_CODE
3.三方拿到授权码后,根据授权码,请求平台的服务端获取token的接口,比如:
curl -X POST 'https://xxx.wanyol.com/open/v1/oauth/token' \ -d 'client_id=<CLIENT_ID>' \ -d 'client_secret=<CLIENT_SECRET>' \ -d 'grant_type=authorization_code' \ -d 'authorization_code=<AUTHORIZATION_CODE>' \ -d 'https://open.gotoxx.com/callback'
4.三方获取token后将token放在请求头中,请求平台数据。
03
HeyTap运动健康开放平台
因为OAhth 2.0授权码的方式是经过广泛验证的有效方案,这里我们结合实际情况,采用Oauth2.0规范,H5授权+云云对接的方式来做,根据三方实际接入和使用场景来阐述具体的方案设计。
3.1 三方申请接入开发平台,需要提交必要资料,审核通过后发放client_id和client_secret。
client_id是用来识别三方的身份的,client_secret用于后面获取token,是三方证明“我真的是我”的凭证。这里特别注意需要三方提供回调域名,即redirect_uri,这是因为我们需要在授权的时候对回调地址做同源验证,防止攻击者篡改回调地址,让用户登录后生成的授权码返回到攻击者网站中。这个数据库模型如下:
3.2 三方应用在合适的地方,配置开放平台的H5授权页面。用户登录成功并勾选授权范围后,向三方返回授权码。
这里有两个重点需要注意下,一是权限,这里采用三级权限的设计,即系统权限,三方
应用权限,三方用户权限。范围逐渐缩小,系统权限,即开发平台系统所有可以对外提供的权限,比如读写用户基本信息的权限,读写用户运动数据的权限。三方应用授权是系统权限的子集,指的是针对具体的三方授予哪些权限,而三方用户权限是三方应用权限的子集,指用户勾选了哪些权限给三方应用。具体数据库模型如下:
二是授权接口。授权接口主要入参有三方clientId,redirectUrl,以及勾选的数据权限scopes
和用户登录后的账号ssoid。其中clientId需要校验是否在开发平台备案,不存在不允许授权。redirectUrl表示授权后的回调地址,向3.1所说到的,这里必须做同源校验。还有一点需要声明,推荐三方应用的的回调地址使用state参数,state 参数是为了保证申请 code 的设备和使用 code 的设备的一致而存在的。开发平台回原封不动的返回。state规则生成复杂一些,攻击者就无从下手了。为了保证安全,授权码authorizationCode时效性只有五分钟。具体数据库模型设计如下:
3.3 三方调用接口用授权码(Authorization Code)获得 accessToken,同时获得一个用于刷新 accessToken 的 refreshToken。
三方获取授权码后,调用接口获取accessToken。接口入参如下:
特别注意,这个接口包含用授权码置换accessToken以及使用refreshToken刷新accessToken,clientSecret是必填的,也要和开放平台的clientSecret一致。出于安全性考虑,accessToken时效为24小时,refreshToken时效时间为30天(每次刷新时都会更新refreshToken为30天)。其中accessToken和refreshToken都包含一些特定的信息,通过AES256 GCM加密和BASE64生成的。
3.4 接口鉴权
数据授权我们说完了,那怎么做鉴权呢?怎么保证三方请求的是合法的,是在用户授予的权限范围内的呢?
三方获得accessToken后,请求平台接口数据时需要在请求头中带上accessToken,我们需要校验accessToken是否存在,存在需要校验是否失效,访问的接口在用户的权限范围内。很自然可以想到,在入口处,采用过滤器,拦截所有三方请求数据的接口(授权和获取token除外),做统一的鉴权处理。为了提供鉴权的效率,我们在3.3中将生成的accessToken放在redis缓存中,key=accessToken,value=用户信息,用户权限信息,accessToken失效时间。所以判断accessToken是否存在是否正确以及是否失效就很简单了,只需要从redis拿到信息做判断即可。
那怎么做用户权限的校验呢?因为我们使用RESTFUL风格的api,这里我采用在每个接口上标记权限注解的方式来做。具体做法是给每个接口备注上权限,然后再spring启动时通过postProcessAfterInitialization接口,将每个接口的url和对应的权限对应起来,放在map中。三方调用接口时,根据请求的url获取map中的权限范围,和redis中用户的权限范围做比对,这样就可以完成鉴权了。
推荐阅读
标签:
推荐阅读
[5.05] 暗喻幻想港中35周年限定版1.03+DLC+金手指+王中王存档
OAuth2.0社交登录流程
相关文章