当前位置: 首页 > news >正文

签名机制 + JWT 鉴权 + Redis 防重放机制​​

完整项目整合:签名机制 + JWT 鉴权 + Redis 防重放机制,这是一个企业级、高安全性前后端分离项目的核心安全架构,适用于:

  • 涉及敏感数据的接口(如支付、用户信息、实名认证)
  • 需要身份认证(JWT)
  • 需要防止请求被篡改(签名)
  • 需要防止请求被重复提交 / 重放攻击(Redis nonce 校验)

✅ 一、目标:整合三大安全机制

模块技术方案作用
1. JWT 鉴权用户登录后返回 JWT Token,后续请求在 Header 中携带,用于身份认证实现「谁在访问」
2. 签名机制(带 timestamp / nonce / sign)前端根据业务参数、时间戳、随机数、密钥生成签名,后端验签防止篡改实现「请求是否被篡改」
3. Redis 防重放(nonce 去重)每个请求携带唯一 nonce,服务端用 Redis 校验该 nonce 是否已使用,防止重复请求实现「请求是否被重放」

✅ 二、整体架构流程(一次安全请求的生命周期)

  1. 用户登录

    • 前端提交用户名密码
    • 后端校验通过,返回 JWT Token
    • 前端存储 Token(如 localStorage)
  2. 发起安全请求(如获取用户信息、支付等)

    • 前端:
      • 携带 JWT Token(Authorization header)
      • 生成:timestamp、nonce、业务参数
      • 用密钥 + 参数生成 sign
      • 发送请求到后端:POST /api/secure-action
    • 后端:
      • 从 Header 解析 JWT,校验用户身份
      • 校验请求中的 timestamp(是否过期)
      • 校验 签名(sign)是否合法
      • 校验 nonce 是否已经使用过(Redis 去重)
      • 全部校验通过 ⇒ 执行业务逻辑
  3. 安全保障

    • ✅ 身份合法(JWT)
    • ✅ 请求未被篡改(签名)
    • ✅ 请求未被重复提交(nonce + Redis)

✅ 三、技术栈与工具

技术说明
后端Spring Boot + Spring Security(可选)+ JWT + Redis
前端Vue 3 + Axios + crypto-js(生成签名)
加密/安全JWT、MD5/SHA256 签名、AES(可选)、Redis
通信协议HTTPS(必须!)

✅ 四、项目模块划分(后端 - Spring Boot)

src/main/java/com/example/secureapi/
├── config/                     # 配置类(可选)
├── controller/
│   ├── AuthController.java         // 登录接口,返回 JWT
│   └── SecureController.java       // 受保护的安全接口(带签名 + nonce 校验)
├── dto/
│   ├── LoginRequest.java
│   └── LoginResponse.java
├── model/                        // 可选,如 User
├── security/                     // JWT 相关(可选)
│   ├── JwtUtil.java
│   └── JwtAuthenticationFilter.java
├── util/
│   ├── SignUtil.java               // 签名生成与校验
│   └── RedisNonceUtil.java         // Redis nonce 去重工具
├── SecureApiApplication.java       // 启动类

✅ 五、1. JWT 鉴权模块(用户登录,返回 Token)

🔐 JwtUtil.java(生成和校验 JWT)

import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import java.security.Key;
import java.util.Date;public class JwtUtil {private static final Key SECRET_KEY = Keys.secretKeyFor(SignatureAlgorithm.HS256);private static final long EXPIRATION_MS = 1000 * 60 * 60 * 24; // 1天public static String generateToken(String username) {return Jwts.builder().setSubject(username).setIssuedAt(new Date()).setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_MS)).signWith(SECRET_KEY).compact();}public static String getUsernameFromToken(String token) {return Jwts.parserBuilder().setSigningKey(SECRET_KEY).build().parseClaimsJws(token).getBody().getSubject();}public static boolean validateToken(String token) {try {Jwts.parserBuilder().setSigningKey(SECRET_KEY).build().parseClaimsJws(token);return true;} catch (Exception e) {return false;}}
}

🛡️ AuthController.java(登录接口返回 JWT)

import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/auth")
public class AuthController {@PostMapping("/login")public Map<String, String> login(@RequestBody LoginRequest request) {// 模拟校验用户名密码(实际应查数据库)if ("admin".equals(request.getUsername()) && "123456".equals(request.getPassword())) {String token = JwtUtil.generateToken(request.getUsername());return Map.of("token", token);} else {throw new RuntimeException("用户名或密码错误");}}
}

🧩 JwtAuthenticationFilter.java(可选,校验请求头中的 JWT)

如果你希望所有安全接口都先校验 JWT 身份,可以实现一个 Spring Filter 拦截请求,解析并校验 JWT,设置用户身份到 SecurityContext。(可参考之前提供的 JWT Filter 示例,或使用 Spring Security 集成)


✅ 六、2. 签名机制模块(timestamp + nonce + sign)

🔐 SignUtil.java(签名生成与校验工具)

import java.util.Map;
import java.util.TreeMap;public class SignUtil {public static String generateSign(Map<String, String> params, String timestamp, String nonce, String secretKey) {TreeMap<String, String> sorted = new TreeMap<>(params);StringBuilder sb = new StringBuilder();for (Map.Entry<String, String> entry : sorted.entrySet()) {sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");}sb.append("timestamp=").append(timestamp).append("&nonce=").append(nonce).append("&key=").append(secretKey);return md5(sb.toString()); // 或 SHA256,推荐生产用 SHA-256}// 简单 MD5,生产推荐使用 crypto-js SHA256,后端对应调整private static String md5(String input) {try {java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");byte[] digest = md.digest(input.getBytes());StringBuilder sb = new StringBuilder();for (byte b : digest) sb.append(String.format("%02x", b));return sb.toString();} catch (Exception e) {throw new RuntimeException(e);}}public static boolean verifySign(Map<String, String> params, String timestamp, String nonce, String secretKey) {String serverSign = generateSign(params, timestamp, nonce, secretKey);String clientSign = params.get("sign");return serverSign != null && serverSign.equals(clientSign);}
}

✅ 七、3. Redis 防重放模块(nonce 去重)

🧠 RedisNonceUtil.java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;@Component
public class RedisNonceUtil {@Autowiredprivate StringRedisTemplate redisTemplate;private static final String NONCE_KEY_PREFIX = "api:nonce:";public boolean isNonceValid(String nonce, long expireSeconds) {Boolean success = redisTemplate.opsForValue().setIfAbsent(NONCE_KEY_PREFIX + nonce,"1",expireSeconds,TimeUnit.SECONDS);return Boolean.TRUE.equals(success);}
}

✅ 八、4. 安全接口(整合 JWT + 签名 + Redis 防重放)

🛡️ SecureController.java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Map;@RestController
@RequestMapping("/api")
public class SecureController {private static final String SECRET_KEY = "my_super_secret_key_123";private static final long TIMESTAMP_WINDOW_MS = 5 * 60 * 1000; // 5分钟private static final long NONCE_EXPIRE_SECONDS = 300; // 5分钟@Autowiredprivate RedisNonceUtil redisNonceUtil;@PostMapping("/secure-action")public Map<String, String> secureAction(@RequestBody Map<String, String> request) {// --- 1. 获取请求参数 ---String token = request.get("token"); // 假设前端把 JWT 放在请求体或 headerString timestamp = request.get("timestamp");String nonce = request.get("nonce");String sign = request.get("sign");// --- 2. 校验 JWT 身份(简化版,真实项目推荐用 Filter 或 Spring Security)---// 这里简化处理,真实项目应该解析 JWT,校验用户名、过期时间等if (token == null || !token.startsWith("Bearer ")) {return Map.of("code", "401", "message", "未提供有效 Token");}String jwt = token.substring(7);if (!JwtUtil.validateToken(jwt)) {return Map.of("code", "401", "message", "Token 无效或已过期");}// --- 3. 校验时间戳(防过期请求)---long reqTime = Long.parseLong(timestamp);long currTime = System.currentTimeMillis();if (Math.abs(currTime - reqTime) > TIMESTAMP_WINDOW_MS) {return Map.of("code", "403", "message", "请求已过期");}// --- 4. 校验签名(防篡改)---// 假设业务参数是 "info",去掉 sign / timestamp / nonce / tokenMap<String, String> params = new java.util.HashMap<>(request);params.remove("sign");params.remove("timestamp");params.remove("nonce");params.remove("token");boolean isSignValid = SignUtil.verifySign(params, timestamp, nonce, SECRET_KEY);if (!isSignValid) {return Map.of("code", "403", "message", "签名校验失败");}// --- 5. 校验 nonce 是否重复(防重放)---boolean isNonceValid = redisNonceUtil.isNonceValid(nonce, NONCE_EXPIRE_SECONDS);if (!isNonceValid) {return Map.of("code", "403", "message", "请求已被重放(nonce 重复)");}// --- 6. 所有校验通过,执行业务逻辑 ---String info = params.getOrDefault("info", "");return Map.of("code", "200", "message", "请求合法,已处理", "data", info);}
}

✅ 九、前端整合(简要说明)

前端需要做:

步骤说明
1. 用户登录调用 /auth/login,获取 JWT Token
2. 每次安全请求携带 Token(如放在请求头 Authorization: Bearer <token> 或请求体)
3. 生成签名用 crypto-js,根据业务参数 + timestamp + nonce + 密钥 生成 sign
4. 生成 nonce每次请求用 Math.random().toString(36).substring(2,15) 或 uuid/nanoid
5. 发送请求把 token、timestamp、nonce、sign、业务参数一起提交到 /api/secure-action

✅ 十、总结:你已完成整合

安全模块是否整合功能
JWT 鉴权用户登录后返回 Token,后续接口鉴权
签名机制防篡改,校验请求参数一致性
Redis 防重放校验 nonce 唯一性,防止请求重复提交
整体安全请求流程身份合法 + 数据可信 + 请求唯一

✅ 十一、安全建议(生产环境必做)

建议说明
使用 HTTPS所有接口必须走 HTTPS,否则签名和 token 可能被窃听
使用 SHA-256 签名MD5 安全性不足,推荐 SHA-256 或 HMAC-SHA256
密钥管理secretKey 不要硬编码,推荐通过登录后下发或使用环境变量
Redis 过期策略nonce 和 timestamp 校验时间窗口要匹配
接口限流与监控对频繁非法请求进行限流、记录、告警

✅ 十二、下一步可扩展

功能说明
Spring Security 集成 JWT更专业的身份认证与权限控制
动态密钥下发登录后返回临时密钥,增强安全性
权限控制(@PreAuthorize)基于角色/权限控制接口访问
完整项目模板 / GitHub 示例如你想要,我可以帮你整理成可运行的项目结构

http://www.dtcms.com/a/496201.html

相关文章:

  • 网站建设的局限性织梦网站文章内容模板
  • BugKu Web渗透 之 都过滤了
  • Qt模块间依赖与解耦问题
  • LoRA 微调大模型直观的理解
  • LeetCode 面试经典 150_栈_简化路径(53_71_C++_中等)(栈+stringstream)
  • 苏中建设集团官方网站微信seo什么意思
  • 网站死链检测工具wordpress 注册邀请码
  • 企业网站结构网站套用模板
  • 2025年--Lc196-712. 两个字符串的最小ASCII删除和(动态规划在字符串的应用)--Java版
  • 淄博有做网站的吗第一免费营销型网站
  • 怎样做模板网站免费网站提交入口
  • 网站建设是要考虑什么东西做网站有底薪吗
  • 买卖合同审查要点及指南
  • Mui框架做网站专项培训网站建设方案
  • Marin说PCB之POC电路layout设计仿真案例---16
  • M部分权限的撤销
  • 建立网站一般多少钱怎样用网站做app
  • 申威(sw_64)架构下如何安装java-1.8.0-swjdk的rpm包?​
  • 性能测试之性能调优详解
  • sql日志打印控制台及存储
  • 青岛城乡住房建设厅网站软件开发外包是什么意思
  • 网站公司的未来中国城乡住房和建设部网站
  • 算法416. 分割等和子集
  • 编织网站建设网站建设考核
  • 2-SpringCloud-Consul服务注册与发现和分布式配置管理
  • 前后端分离项目java+vue 加密一般用几种加密方式,具体是什么加密,怎么用的
  • 从零掌握贪心算法Java版:LeetCode 10题实战解析(上)
  • matlab_学习_均分数据
  • 深圳免费建站山东省建设节能协会网站
  • 青岛万维网站设计珠宝类企业网站(手机端)