博客
关于我
ssh,ssm整合redis存储验证码
阅读量:813 次
发布时间:2019-03-25

本文共 4646 字,大约阅读时间需要 15 分钟。

SSH和SSM整合Redis存储验证码


SSM框架下Redis存储验证码

在SSM框架中,我们可以使用Redis存储验证码,解决后端和前端之间的验证问题。以下是详细的解决方案。


思路

  • 登录界面请求验证码:用户在登录界面提交账号和密码。此时,我们需要生成一个随机验证码,并将其以图片形式返回给前台客户端。

  • 生成验证码并存储到Redis:后台生成随机验证码,将对应的verificationJwt令牌作为Redis的键,存储验证码作为值。

  • 返回verificationJwt令牌:将刚生成的verificationJwt令牌放在响应头中,传送到前台客户端。

  • 客户端验证:前台客户端将输入的验证码与Redis中存储的验证码进行对比,验证是否一致。


  • 验证流程

  • 后端生成验证码并存储到Redis

    • 后端随机生成4位字符或数字。
    • 使用ImageUtil生成随机验证码图片,并将验证码转换为base64字符串。
    • 存储到Redis中,键为 verificationJwt令牌,值为生成的验证码。
  • 前端显示验证码:将base64图片发送到前台,展示给用户输入。

  • 前台提交验证码:用户填写用户名、密码和验证码后,提交登录请求。

  • 后端验证验证码

    • 后端根据用户提交的verificationJwt令牌,从Redis中获取存储的验证码。
    • 将获取到的验证码与用户输入的验证码比较,判断是否正确。

  • 实现步骤

  • 前端代码

    • State.js:定义vuex存储verificationJwt。
    • action.js:定义API接口,用于获取验证码和登录。
    • http.js:配置axios拦截器,处理Jwt令牌。
  • 后端代码

    • UserController:负责处理登录和验证码验证。
    • UserAction:核心业务逻辑,构建请求。
    • ImageUtil:生成随机验证码并转base64。
    • Jedis:Redis Java客户端操作。
  • 配置文件

    • redis.properties:配置Redis连接信息。
    • web.xml:配置过滤器和邻接方。
    • pom.xml:添加Redis依赖和相关日志配置。

  • 重要技术点

    • Redis存储:使用Redis的角色主要是为了快速存取和验证验证码,避免了数据库的IO压力。
    • Jwt令牌验证:使用JwtUtils生成和验证令牌,确保通信安全。
    • 前后端协同:前台提交验证码时,带上verificationJwt令牌,后台根据令牌查询Redis数据。

    解决方案代码

    前端

    // State.jsexport default {    verificationJwt: null,    options: [],    activeIndex: '',    showName: 'show',    role: "nopass",}// Mutations.jssetVerificationJwt: (state, payload) => {    state.verificationJwt = payload.verificationJwt;}// Getters.jsgetVerificationJwt: (state) => {    return state.verificationJwt;}
    // action.jsexport default {    url: {        SYSTEM_USER_DOLOGIN: '/vue/user/login',        VERAIFICATION: '/vue/user/verificationCode'    }}
    // http.jsconst axios = require('axios').create({    baseURL: action.SERVER,    headers: {        'verificationJwt': '',        'jwt': ''    }});axios.interceptors.request.use((config) => {    const verificationJwt = store.get('verificationJwt');    config.headers.verificationJwt = verificationJwt;    config.headers.jwt = verificationJwt;    return config;});axios.interceptors.response.use((response) => {    const verificationJwt = response.headers.verificationJwt;    if (verificationJwt) {        store.commit('setVerificationJwt', {            verificationJwt: verificationJwt        });    }    return response;});

    后端

    // UserActionpublic String login(User user) {    String verificationCode = request.getParameter("verificationCode");    String jwt = request.getHeader(JwtConstants.verificationJwt);    Object redisVerificationCode = redisTemplate.opsForValue().get(jwt);    if (StringUtils.isBlank(verificationCode)) {        return ResponseUtil.error("验证码已超时");    }    if (!StringUtils.equals(verificationCode.toLowerCase(), redisVerificationCode.toString().toLowerCase())) {        return ResponseUtil.error("验证码错误");    }    User loginUser = userService.login(user);    if (loginUser != null) {        Map
    claims = new HashMap<>(); claims.put("username", loginUser.getUsername()); claims.put("password", loginUser.getPassword()); String jwtToken = JwtUtils.createJwt(claims, JwtUtils.JWT_WEB_TTL); response.setHeader(JwtConstants.verificationJwt, jwtToken); return ResponseUtil.success(loginUser); } else { return ResponseUtil.error("账号或密码错误"); }}
    // ImageUtilpublic static String createImageWithVerifyCode(String word, int width, int height) {    BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);    Graphics graphics = bufferedImage.getGraphics();    graphics.setColor getRandomColor(160, 200);    graphics.fillRect(0, 0, width, height);    graphics.setColor(Color.white);    graphics.drawRect(0, 0, width - 1, height - 1);    Graphics2D graphics2d = (Graphics2D) graphics;    Random random = new Random();    int x = 10;    for (int i = 0; i < word.length(); i++) {        graphics2d.setColor(new Color(random.nextInt(110) + 20, random.nextInt(110) + 20, random.nextInt(110) + 20));        int jiaodu = random.nextInt(60) - 30;        double theta = jiaodu * Math.PI / 180;        char c = word.charAt(i);        graphics2d.rotate(theta, x, 20);        graphics2d.drawString(String.valueOf(c), x, 20);        graphics2d.rotate(-theta, x, 20);        x += 30;    }    graphics.dispose();    ByteArrayOutputStream baos = new ByteArrayOutputStream();    ImageIO.write(bufferedImage, "png", baos);    byte[] bytes = baos.toByteArray();    BASE64Encoder encoder = new BASE64Encoder();    String pngBase64 = encoder.encodeBuffer(bytes).trim().replace("\\n", "").replace("\\r", "");    return pngBase64;}

    其他配置

  • Redis依赖
  • redis.clients
    jedis
    ${redis.version}
    1. 用户登录验证

    2. 通过以上方案,我们可以实现一个高效的RFC 7633规范的验证码登录系统,确保用户信息的安全性和访问的唯一性。

    转载地址:http://qfoyk.baihongyu.com/

    你可能感兴趣的文章
    Multisim中555定时器使用技巧
    查看>>
    MySQL CRUD 数据表基础操作实战
    查看>>
    multisim变压器反馈式_穿过隔离栅供电:认识隔离式直流/ 直流偏置电源
    查看>>
    mysql csv import meets charset
    查看>>
    multivariate_normal TypeError: ufunc ‘add‘ output (typecode ‘O‘) could not be coerced to provided……
    查看>>
    MySQL DBA 数据库优化策略
    查看>>
    multi_index_container
    查看>>
    mutiplemap 总结
    查看>>
    MySQL Error Handling in Stored Procedures---转载
    查看>>
    MVC 区域功能
    查看>>
    MySQL FEDERATED 提示
    查看>>
    mysql generic安装_MySQL 5.6 Generic Binary安装与配置_MySQL
    查看>>
    Mysql group by
    查看>>
    MySQL I 有福啦,窗口函数大大提高了取数的效率!
    查看>>
    mysql id自动增长 初始值 Mysql重置auto_increment初始值
    查看>>
    MySQL in 太多过慢的 3 种解决方案
    查看>>
    Mysql Innodb 锁机制
    查看>>
    MySQL InnoDB中意向锁的作用及原理探
    查看>>
    MySQL InnoDB事务隔离级别与锁机制深入解析
    查看>>
    Mysql InnoDB存储引擎 —— 数据页
    查看>>