若依集成aj-captcha实现滑块验证码

集成aj-captcha实现滑块验证码

借用官方文档,加入一些自己的理解:


集成以AJ-Captcha滑块验证码为例,不需要键盘手动输入,极大优化了传统验证码用户体验不佳的问题。目前对外提供两种类型的验证码,其中包含滑动拼图、文字点选。

后端实现

1、ruoyi-framework\pom.xml添加依赖


<dependency>
	<groupId>com.github.anji-plusgroupId>
	<artifactId>captcha-spring-boot-starterartifactId>
	<version>1.2.7version>
dependency>


2、修改ruoyi-admin中的application.yml,加入aj-captcha配置

# 滑块验证码
aj:
   captcha:
      # 缓存类型
      cache-type: redis
      # blockPuzzle 滑块 clickWord 文字点选  default默认两者都实例化
      type: blockPuzzle
      # 右下角显示字
      water-mark: ruoyi.vip
      # 校验滑动拼图允许误差偏移量(默认5像素)
      slip-offset: 5
      # aes加密坐标开启或者禁用(true|false)
      aes-status: true
      # 滑动干扰项(0/1/2)
      interference-options: 2

同时在

ruoyi-admin\src\main\resources\META-INF\services下创建

com.anji.captcha.service.CaptchaCacheService.java文件同时设置文件内容为

com.ruoyi.framework.web.service.CaptchaRedisService

3、在ruoyi-framework\src\main\java\con\ruoyi\framework\config中的SecurityConfig中设置httpSecurity配置匿名访问

.antMatchers("/login", "/captcha/get", "/captcha/check").permitAll()
或者
.antMatchers("/login", "/register","/captcha/get","/captcha/check").anonymous()

4、修改相关类

可以移除不需要的类(以前的验证码类)

ruoyi-admin\com\ruoyi\web\controller\common\CaptchaController.java

ruoyi-framework\com\ruoyi\framework\config\CaptchaConfig.java

ruoyi-framework\com\ruoyi\framework\config\KaptchaTextCreator.java


修改ruoyi-admin\com\ruoyi\web\controller\system\SysLoginController.java 中的登录方法

/**
 * 登录方法
 * 
 * @param loginBody 登录信息
 * @return 结果
 */
@PostMapping("/login")
public AjaxResult login(@RequestBody LoginBody loginBody)
{
	AjaxResult ajax = AjaxResult.success();
	// 生成令牌
	String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode());
	ajax.put(Constants.TOKEN, token);
	return ajax;
}

修改ruoyi-framework\com\ruoyi\framework\web\service\SysLoginService.java

package com.ruoyi.framework.web.service;

import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import com.anji.captcha.model.common.ResponseModel;
import com.anji.captcha.model.vo.CaptchaVO;
import com.anji.captcha.service.CaptchaService;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.exception.user.CaptchaException;
import com.ruoyi.common.exception.user.UserPasswordNotMatchException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.system.service.ISysUserService;

/**
 * 登录校验方法
 * 
 * @author ruoyi
 */
@Component
public class SysLoginService
{
    @Autowired
    private TokenService tokenService;

    @Resource
    private AuthenticationManager authenticationManager;

    @Autowired
    private ISysUserService userService;

    @Autowired
    @Lazy
    private CaptchaService captchaService;

    /**
     * 登录验证
     * 
     * @param username 用户名
     * @param password 密码
     * @param code 验证码
     * @return 结果
     */
    public String login(String username, String password, String code)
    {
        CaptchaVO captchaVO = new CaptchaVO();
        captchaVO.setCaptchaVerification(code);
        ResponseModel response = captchaService.verification(captchaVO);
        if (!response.isSuccess())
        {
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL,
                    MessageUtils.message("user.jcaptcha.error")));
            throw new CaptchaException();
        }
        // 用户验证
        Authentication authentication = null;
        try
        {
            // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
            authentication = authenticationManager
                    .authenticate(new UsernamePasswordAuthenticationToken(username, password));
        }
        catch (Exception e)
        {
            if (e instanceof BadCredentialsException)
            {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
                throw new UserPasswordNotMatchException();
            }
            else
            {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));
                throw new ServiceException(e.getMessage());
            }
        }
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        // 生成token
        return tokenService.createToken(loginUser);
    }

    /**
     * 记录登录信息
     *
     * @param userId 用户ID
     */
    public void recordLoginInfo(Long userId)
    {
        SysUser sysUser = new SysUser();
        sysUser.setUserId(userId);
        sysUser.setLoginIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
        sysUser.setLoginDate(DateUtils.getNowDate());
        userService.updateUserProfile(sysUser);
    }
}

新建 ruoyi-framework\com\ruoyi\framework\web\service\CaptchaRedisService.java

package com.ruoyi.framework.web.service;

import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import com.anji.captcha.service.CaptchaCacheService;

/**
 * 自定义redis验证码缓存实现类
 * 
 * @author ruoyi
 */
public class CaptchaRedisService implements CaptchaCacheService
{
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public void set(String key, String value, long expiresInSeconds)
    {
        stringRedisTemplate.opsForValue().set(key, value, expiresInSeconds, TimeUnit.SECONDS);
    }

    @Override
    public boolean exists(String key)
    {
        return stringRedisTemplate.hasKey(key);
    }

    @Override
    public void delete(String key)
    {
        stringRedisTemplate.delete(key);
    }

    @Override
    public String get(String key)
    {
        return stringRedisTemplate.opsForValue().get(key);
    }

    @Override
    public Long increment(String key, long val)
    {
        return stringRedisTemplate.opsForValue().increment(key, val);
    }

    @Override
    public String type()
    {
        return "redis";
    }
}

前端实现

5、添加滑动验证码插件到ruoyi-ui

下载前端插件相关包和代码实现ruoyi-vue/集成滑动验证码.zip

链接: https://pan.baidu.com/s/13JVC9jm-Dp9PfHdDDylLCQ 提取码: y9jt

下载后打开ruoyi-vue \集成aj-captcha实现滑块验证码

在ruoyi-ui终端安装 npm install crypto-js --save-dev

再按照目录结构,把 api\login.js替换,views/login.vue替换,静态资源组件复制进去就ok了

你可能感兴趣的:(前端,spring,boot,vue)