博客
关于我
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/

    你可能感兴趣的文章
    Mysql 语句操作索引SQL语句
    查看>>
    MySQL 误操作后数据恢复(update,delete忘加where条件)
    查看>>
    MySQL 调优/优化的 101 个建议!
    查看>>
    mysql 转义字符用法_MySql 转义字符的使用说明
    查看>>
    mysql 输入密码秒退
    查看>>
    mysql 递归查找父节点_MySQL递归查询树状表的子节点、父节点具体实现
    查看>>
    mysql 里对root及普通用户赋权及更改密码的一些命令
    查看>>
    Mysql 重置自增列的开始序号
    查看>>
    MySQL 错误
    查看>>
    MySQL 面试,必须掌握的 8 大核心点
    查看>>
    MySQL 高可用性之keepalived+mysql双主
    查看>>
    MySql-2019-4-21-复习
    查看>>
    mysql-connector-java各种版本下载地址
    查看>>
    mysql-group_concat
    查看>>
    MySQL-redo日志
    查看>>
    MySQL-【1】配置
    查看>>
    MySQL-【4】基本操作
    查看>>
    Mysql-丢失更新
    查看>>
    Mysql-事务阻塞
    查看>>
    Mysql-存储引擎
    查看>>