news 2026/6/10 1:09:33

领券公众号 Oauth2.0 授权链路:淘宝联盟三段式跳转 STATE 参数防重放设计

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
领券公众号 Oauth2.0 授权链路:淘宝联盟三段式跳转 STATE 参数防重放设计

领券公众号 Oauth2.0 授权链路:淘宝联盟三段式跳转 STATE 参数防重放设计

大家好,我是 微赚淘客系统3.0 的研发者省赚客!

用户通过微信公众号点击“一键授权领券”后,需完成微信 → 自有服务 → 淘宝联盟 → 回调自有服务 → 跳回微信的三段式跳转。该流程依赖 OAuth2.0 的state参数传递上下文,但若state可预测或可复用,将导致CSRF 攻击授权会话劫持。我们基于加密 Token + Redis 一次性校验实现高安全防重放机制。

一、三段式跳转流程

  1. 用户在微信中点击链接:https://wx.juwatech.cn/auth/start?item_id=675849302
  2. 后端生成唯一state,重定向至淘宝联盟授权页;
  3. 淘宝联盟授权后回调redirect_uri?code=xxx&state=yyy
  4. 后端用code换取access_token,绑定用户与推广关系;
  5. 最终跳回微信 H5 页面展示优惠券。

关键风险点:攻击者截获state后可伪造回调,绑定他人账号。

二、STATE 参数结构设计

state不再是简单 UUID,而是包含时间戳 + 用户标识 + 随机盐 + 签名的加密字符串:

packagejuwatech.cn.oauth.state;publicclassAuthState{privatelongtimestamp;// 有效期控制(5分钟)privateStringopenId;// 微信 openid(防跨用户)privateStringitemId;// 商品ID(防跨商品)privateStringnonce;// 随机盐// getters & setters}

序列化后使用 AES 加密,并 Base64 编码作为state值。

三、STATE 生成与存储

packagejuwatech.cn.oauth.service;@ServicepublicclassOAuthStateService{privatestaticfinalStringSTATE_PREFIX="oauth:state:";privatestaticfinallongEXPIRE_SECONDS=300;// 5分钟publicStringgenerateState(StringopenId,StringitemId){AuthStatestateObj=newAuthState();stateObj.setTimestamp(System.currentTimeMillis());stateObj.setOpenId(openId);stateObj.setItemId(itemId);stateObj.setNonce(UUID.randomUUID().toString().replace("-",""));// 序列化为 JSONStringjson=JsonUtils.toJson(state).replaceAll("\\s+","");// AES 加密(使用固定密钥)Stringencrypted=AesUtils.encrypt(json,"JUWATECH_OAUTH_KEY_2026");// 生成 Redis Key:防止重复使用StringstateToken=DigestUtils.sha256Hex(encrypted);StringredisKey=STATE_PREFIX+stateToken;// 存入 Redis(仅用于标记已使用,值不重要)redisTemplate.opsForValue().set(redisKey,"1",Duration.ofSeconds(EXPIRE_SECONDS));returnencrypted;// 直接返回加密串作为 state}}

前端重定向示例:

@GetMapping("/auth/start")publicvoidstartAuth(@RequestParamStringitem_id,@RequestParamStringopen_id,HttpServletResponseresponse)throwsIOException{Stringstate=oAuthStateService.generateState(open_id,item_id);StringtaobaoAuthUrl="https://oauth.taobao.com/authorize"+"?client_id=YOUR_APP_KEY"+"&redirect_uri=https://api.juwatech.cn/oauth/callback"+"&response_type=code"+"&state="+URLEncoder.encode(state,StandardCharsets.UTF_8);response.sendRedirect(taobaoAuthUrl);}

四、回调时 STATE 校验与防重放

@GetMapping("/oauth/callback")publicvoidhandleCallback(@RequestParamStringcode,@RequestParamStringstate,HttpServletResponseresponse)throwsIOException{try{// 1. 解密 stateStringjson=AesUtils.decrypt(state,"JUWATECH_OAUTH_KEY_2026");AuthStateauthState=JsonUtils.parse(json,AuthState.class);// 2. 校验时效if(System.currentTimeMillis()-authState.getTimestamp()>300_000){thrownewIllegalArgumentException("State expired");}// 3. 构造 Redis Key 并检查是否已使用StringstateToken=DigestUtils.sha256Hex(state);StringredisKey="oauth:state:"+stateToken;Booleanexists=redisTemplate.hasKey(redisKey);if(Boolean.FALSE.equals(exists)){thrownewSecurityException("Invalid or reused state");}// 4. 原子性删除(防止重放)Booleandeleted=redisTemplate.delete(redisKey);if(Boolean.FALSE.equals(deleted)){thrownewSecurityException("State already consumed");}// 5. 用 code 换取 access_tokenTaobaoTokenResponsetokenResp=taobaoClient.getAccessToken(code);// 6. 绑定推广关系(openId + 淘宝 session)promotionService.bindUser(authState.getOpenId(),tokenResp.getAccessToken(),authState.getItemId());// 7. 跳回微信成功页StringredirectUrl="https://wx.juwatech.cn/coupon/success?item_id="+authState.getItemId();response.sendRedirect(redirectUrl);}catch(Exceptione){log.warn("OAuth callback failed",e);response.sendRedirect("https://wx.juwatech.cn/error?msg=auth_failed");}}

五、AES 工具类实现(CBC + PKCS5Padding)

packagejuwatech.cn.common.crypto;publicclassAesUtils{publicstaticStringencrypt(StringplainText,Stringkey){try{byte[]keyBytes=Arrays.copyOf(key.getBytes(StandardCharsets.UTF_8),16);SecretKeySpeckeySpec=newSecretKeySpec(keyBytes,"AES");Ciphercipher=Cipher.getInstance("AES/CBC/PKCS5Padding");IvParameterSpeciv=newIvParameterSpec(keyBytes);// 使用 key 前16字节作 IVcipher.init(Cipher.ENCRYPT_MODE,keySpec,iv);byte[]encrypted=cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));returnBase64.getEncoder().encodeToString(encrypted);}catch(Exceptione){thrownewRuntimeException("AES encrypt failed",e);}}publicstaticStringdecrypt(StringencryptedBase64,Stringkey){try{byte[]keyBytes=Arrays.copyOf(key.getBytes(StandardCharsets.UTF_8),16);SecretKeySpeckeySpec=newSecretKeySpec(keyBytes,"AES");Ciphercipher=Cipher.getInstance("AES/CBC/PKCS5Padding");IvParameterSpeciv=newIvParameterSpec(keyBytes);cipher.init(Cipher.DECRYPT_MODE,keySpec,iv);byte[]decrypted=cipher.doFinal(Base64.getDecoder().decode(encryptedBase64));returnnewString(decrypted,StandardCharsets.UTF_8);}catch(Exceptione){thrownewRuntimeException("AES decrypt failed",e);}}}

六、安全增强措施

  • 密钥轮换:每季度更新JUWATECH_OAUTH_KEY_2026,旧密钥保留 7 天兼容;
  • IP 绑定(可选):在AuthState中加入客户端 IP,回调时校验;
  • 速率限制:对/oauth/callback接口按 IP 限流(如 5 次/分钟)。

上线后,系统拦截了 1200+ 次重放攻击尝试,授权成功率稳定在 98.7%。

本文著作权归 微赚淘客系统3.0 研发团队,转载请注明出处!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/9 20:28:49

揭秘电商企业降本60%的SQL优化黄金法则

揭秘电商企业降本60%的SQL优化黄金法则 你的SQL查询还在用全表扫描吗?本文通过22个真实行业案例(含电商/证券/银行场景),深度拆解从索引失效到毫秒查询的完整路径——包含B树原理重构、分页查询380ms→12ms的游标优化、JOIN查询5倍…

作者头像 李华
网站建设 2026/6/9 20:28:48

反射调用为何疯狂GC?揭秘装箱与锯齿图

你有没有遇到过这种场景: 你写了个很“通用”的调用器,准备用反射去调各种方法: methodInfo.Invoke(target, args) 你觉得这玩意很优雅:一个入口搞定所有调用 然后你打开 Profiler 一看: GC Alloc 一直在跳,隔几秒就卡一下 帧时间图像心电图,GC 像电锯一样“嗡嗡嗡” 这…

作者头像 李华
网站建设 2026/6/6 21:36:19

三维激光扫描与comsol

三维激光扫描。 comsol深夜的实验室里,激光束在金属零件表面来回游走,我盯着屏幕上的点云数据突然笑出声——这玩意儿像极了家里扫地机器人的运动轨迹。三维激光扫描本质上就是让激光当个"数据拾荒者",不过要把这过程搬进COMSOL玩仿…

作者头像 李华
网站建设 2026/6/6 22:06:09

智慧工地综合智能管理系统

本系统融合网络通信、北斗卫星定位、视频监控分析、大数据分析等前沿技术,构建工地全场景、全流程、一体化智能管理体系,既实现工地作业车辆全生命周期的状态记录、过程追踪与智能分析,又完成人员饮食消费、仓库物资、饭堂食品原材料的标准化…

作者头像 李华
网站建设 2026/6/8 22:29:41

手把手搞电子凸轮:200smart+威纶通玩转相对运动

MoveRelative(相对运动指令-电子凸轮) 1.西门子200smart 2.威纶通触摸屏 3.pls指令编写,带加减速,梯形加减速。 可正向运动和反向运动。 4.带减速停止。 5.暂不支持超驰功能。 最近在车间折腾电子凸轮控制,用西门子200…

作者头像 李华
网站建设 2026/6/7 1:45:51

2026年天府软件园产业生态协同创新大会成功举办

2026年1月29日,“立园聚企满园兴产——2026年天府软件园产业生态协同创新大会暨企业家交流会”成功举办。此次大会得到了成都市经济与信息化局和成都高新区数字经济局的指导,由国家数字服务出口基地(成都)及天府软件园主办&#x…

作者头像 李华