【JAVA】使用Redis+Jwt技术生成图片验证码

本文介绍了如何在后端使用Java创建图像验证码,包括生成随机字符、添加干扰线和噪点,然后将验证码及其键值对存入Redis。同时,文章还展示了如何在前端获取验证码并将其传回后端进行逻辑校验的过程。

思路:后端生成验证码,将对应的key和value存放到redis,生成图形化验证码返回给前端,前端输入验证码将参数传给后端做逻辑校验。

一、图片验证码生成工具类

public class CreateImageCode {
    // 图片的宽度。
    private int width = 120;
    // 图片的高度。
    private int height = 40;
    // 验证码字符个数
    private int codeCount = 4;
    // 验证码干扰线数
    private int lineCount = 30;
    // 验证码
    private String code = null;
    // 验证码图片Buffer
    private BufferedImage buffImg = null;
    Random random = new Random();

    public CreateImageCode() {
        creatImage();
    }

    public CreateImageCode(int width, int height) {
        this.width = width;
        this.height = height;
        creatImage();
    }

    public CreateImageCode(int width, int height, int codeCount) {
        this.width = width;
        this.height = height;
        this.codeCount = codeCount;
        creatImage();
    }
    public CreateImageCode(int width, int height, int codeCount, int lineCount) {
        this.width = width;
        this.height = height;
        this.codeCount = codeCount;
        this.lineCount = lineCount;
        creatImage();
    }

    // 生成图片
    private void creatImage() {
        int fontWidth = width / codeCount;// 字体的宽度
        int fontHeight = height - 5;// 字体的高度
        int codeY = height - 8;

        // 图像buffer
        buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics g = buffImg.getGraphics();
        //Graphics2D g = buffImg.createGraphics();
        // 设置背景色
        g.setColor(getRandColor(200, 250));
      
### 生成包含验证码校验、用户名密码认证和 JWT 生成Redis 存储的代码示例 在 Spring Boot 应用中,结合 Redis 实现验证码校验、用户名密码认证,并生成 JWT Token 是一种常见的安全认证方案。以下是一个完整的实现示例,涵盖验证码生成、用户登录、JWT 生成Redis 缓存的使用。 --- #### 3.1 验证码生成与存储 验证码生成使用 `BufferedImage` 创建图片,并将验证码值存入 Redis,设置过期时间以防止重复使用。 ```java import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.util.Random; import javax.imageio.ImageIO; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; @Service public class CaptchaService { private final StringRedisTemplate redisTemplate; public CaptchaService(StringRedisTemplate redisTemplate) { this.redisTemplate = redisTemplate; } public String generateCaptcha(String key) { String code = generateRandomCode(6); redisTemplate.opsForValue().set("captcha:" + key, code, 5, TimeUnit.MINUTES); return code; } private String generateRandomCode(int length) { String chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; StringBuilder sb = new StringBuilder(); Random rnd = new Random(); for (int i = 0; i < length; i++) { sb.append(chars.charAt(rnd.nextInt(chars.length()))); } return sb.toString(); } } ``` --- #### 3.2 用户名密码认证与 JWT 生成 用户登录接口接收用户名、密码和验证码,验证通过后生成 JWT Token。 ```java import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.stereotype.Service; @Service public class AuthService { private final AuthenticationManager authenticationManager; private final JwtTokenUtil jwtTokenUtil; private final UserDetailsService userDetailsService; private final StringRedisTemplate redisTemplate; public AuthService(AuthenticationManager authenticationManager, JwtTokenUtil jwtTokenUtil, UserDetailsService userDetailsService, StringRedisTemplate redisTemplate) { this.authenticationManager = authenticationManager; this.jwtTokenUtil = jwtTokenUtil; this.userDetailsService = userDetailsService; this.redisTemplate = redisTemplate; } public String login(String username, String password, String captchaKey, String captchaInput) { String storedCaptcha = redisTemplate.opsForValue().get("captcha:" + captchaKey); if (storedCaptcha == null || !storedCaptcha.equalsIgnoreCase(captchaInput)) { throw new RuntimeException("验证码错误或已过期"); } Authentication authentication = authenticationManager.authenticate( new UsernamePasswordAuthenticationToken(username, password) ); UserDetails userDetails = userDetailsService.loadUserByUsername(username); return jwtTokenUtil.generateToken(userDetails); } } ``` --- #### 3.3 JWT 工具类实现 JWT 工具类负责生成和解析 Token,使用 `jjwt` 库实现。 ```java import io.jsonwebtoken.*; import org.springframework.stereotype.Component; import java.util.Date; @Component public class JwtTokenUtil { private static final String SECRET_KEY = "your-secret-key"; private static final long EXPIRATION = 86400000; // 24小时 public String generateToken(UserDetails userDetails) { return Jwts.builder() .setSubject(userDetails.getUsername()) .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION)) .signWith(SignatureAlgorithm.HS512, SECRET_KEY) .compact(); } public String extractUsername(String token) { return Jwts.parser() .setSigningKey(SECRET_KEY) .parseClaimsJws(token) .getBody() .getSubject(); } public boolean validateToken(String token, UserDetails userDetails) { String username = extractUsername(token); return username.equals(userDetails.getUsername()) && !isTokenExpired(token); } private boolean isTokenExpired(String token) { Date expiration = Jwts.parser() .setSigningKey(SECRET_KEY) .parseClaimsJws(token) .getBody() .getExpiration(); return expiration.before(new Date()); } } ``` --- #### 3.4 Redis 配置与使用 配置 Redis 缓存验证码使用 `StringRedisTemplate` 存储字符串类型数据。 ```java import org.springframework.context.annotation.Bean; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Component; @Component public class RedisConfig { @Bean public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) { return new StringRedisTemplate(factory); } } ``` --- #### 3.5 登录接口控制器 定义 REST 接口用于处理登录请求。 ```java import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class AuthController { private final AuthService authService; public AuthController(AuthService authService) { this.authService = authService; } @PostMapping("/login") public String login(@RequestParam String username, @RequestParam String password, @RequestParam String captchaKey, @RequestParam String captchaInput) { return authService.login(username, password, captchaKey, captchaInput); } } ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值