跳到正文
Joeplover
后端开发·2025-10-03·约 3 分钟阅读

SVHHS 用户系统:JWT 认证 + Redis 缓存 + OSS 存储

Spring Boot 实战项目,集成 JWT 登录认证、Redis Token 管理、阿里云 OSS 文件存储和 MD5 加密。

用户认证系统

SVHHS 用户系统:JWT 认证 + Redis 缓存 + OSS 存储

项目结构

SVHHS 是一个基于 Spring Boot 的用户管理系统,集成了 Web 开发中三个最基础也最重要的能力:认证(JWT)、缓存(Redis)、文件存储(OSS)。

JWT 认证

登录流程

用户登录 → 验证用户名密码 → 生成 JWT Token → 返回给前端
前端后续请求 → 在 Header 中携带 Token → 过滤器解析验证 → 获取用户信息

JWT 结构

public String generateToken(UserDetails user) {
    return Jwts.builder()
        .setSubject(user.getUsername())
        .claim("role", user.getRole())
        .setIssuedAt(new Date())
        .setExpiration(new Date(System.currentTimeMillis() + 86400000)) // 24 小时
        .signWith(SignatureAlgorithm.HS256, secretKey)
        .compact();
}

三个部分:

  1. Header:算法类型(HS256)
  2. Payload:用户信息(sub/role/exp/iat),Base64 编码不是加密
  3. Signature:对前两部分的签名防止篡改

安全问题

JWT 最大的误解是"Payload 是加密的"——实际上 Payload 只是 Base64 编码,任何拿到 Token 的人都可以解码看到里面的内容。

// 解码 JWT Payload(不需要密钥)
String[] parts = token.split("\.");
byte[] payload = Base64.getDecoder().decode(parts[1]);
System.out.println(new String(payload));
// {"sub":"admin","role":"ADMIN","exp":1700000000}

不要在 Payload 中放敏感信息(密码、身份证号等)。如果需要加密整个 JWT,使用 JWE(JSON Web Encryption)。

Redis 缓存热点数据

对频繁查询的用户数据进行缓存:

@Service
public class UserService {
    
    @Cacheable(value = "users", key = "#username")
    public User findByUsername(String username) {
        // 此方法只在缓存未命中时执行
        return userRepository.findByUsername(username);
    }
    
    @CacheEvict(value = "users", key = "#username")
    public void updateUser(String username, UserUpdateRequest request) {
        userRepository.updateByUsername(username, request);
    }
}

缓存策略:

  • 读多写少的数据(用户基本信息)非常适合缓存
  • cache-aside 模式:读优先查缓存,写时更新数据库 + 删除缓存
  • TTL 设置:用户信息类缓存 30 分钟,避免数据长期不一致

OSS 文件存储

文件上传流程:

前端上传 → 后端接收 MultipartFile → 上传到 OSS → 获取 URL → 存入数据库
public String uploadFile(MultipartFile file) {
    String filename = UUID.randomUUID().toString() + 
                      FilenameUtils.getExtension(file.getOriginalFilename());
    ossClient.putObject(bucketName, filename, file.getInputStream());
    return ossClient.generatePresignedUrl(bucketName, filename, 
                                          expiration).toString();
}

大流量时的优化

如果应用流量大,每次文件都经后端转发会占用大量带宽。优化方案:前端直传。

优化前:前端 → 后端 → OSS(经过服务器转发,占用带宽)
优化后:前端 → 获取上传凭证 → 直传 OSS(后端只签名不传文件)

使用 OSS 的 PostObject 签名机制:后端生成签名 URL,前端直接用这个 URL 上传文件,文件不经过后端服务器。

总结

SVHHS 整合了 Web 开发的三个标配能力。理解 JWT 的"不加密"风险、Redis 缓存的最佳实践、OSS 的直传优化,对任何 Web 项目都有用。