Spring Boot +Vue
环境要求:Jdk1.8以上版本、MySql数据库、Redis、Maven、Vue
官网地址:RuoYi-Vue: 🎉 基于SpringBoot,Spring Security,JWT,Vue & Element 的前后端分离权限管理系统,同时提供了 Vue3 的版本 (gitee.com)

目录:


MySQL配置后的效果:

在工程中配置数据库(改为本地数据库):



打开浏览器,访问8080端口,出现如下,则访问成功:

1.安装依赖

2运行前端

若Node.js版本高,则需要在package.json中修改配置:
- "scripts": {
- "dev": "set NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve",
- "build:prod": "vue-cli-service build",
- "build:stage": "vue-cli-service build --mode staging",
- "preview": "node build/index.js --preview",
- "lint": "eslint --ext .js,.vue src"
- }
运行成功后:

基本思路:后端生成一个表达式,例如:2+2=?@4,然后把题干2+2=?生成图片、和一个唯一的key传到前端;把结果4(value),和唯一的key做键存到redis。
1.页面中的函数相关代码(login.vue):

2.获取验证码的请求封装(api/login.js):


统一的请求前缀:


3.利用反向代理,url请求前端,进行代理,映射转发到后端,用于解决跨域问题。代理的配置部分在:
达到的效果:http:localhost/dev-api/captcheImage ---->http:localhost/captcheImage

- /**
- * 生成验证码
- */
- @GetMapping("/captchaImage")
- public AjaxResult getCode(HttpServletResponse response) throws IOException
- {
- AjaxResult ajax = AjaxResult.success();
- boolean captchaEnabled = configService.selectCaptchaEnabled();//判断是否开启验证
- ajax.put("captchaEnabled", captchaEnabled);
- if (!captchaEnabled)
- {
- return ajax;
- }
-
- // 保存验证码信息
- String uuid = IdUtils.simpleUUID();
- String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid;
-
- String capStr = null, code = null;
- BufferedImage image = null;
-
- // 生成验证码
- String captchaType = RuoYiConfig.getCaptchaType();
- if ("math".equals(captchaType))
- {
- String capText = captchaProducerMath.createText();
- capStr = capText.substring(0, capText.lastIndexOf("@"));
- code = capText.substring(capText.lastIndexOf("@") + 1);
- image = captchaProducerMath.createImage(capStr);
- }
- else if ("char".equals(captchaType))
- {
- capStr = code = captchaProducer.createText();
- image = captchaProducer.createImage(capStr);
- }
-
- redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
- // 转换流信息写出
- FastByteArrayOutputStream os = new FastByteArrayOutputStream();
- try
- {
- ImageIO.write(image, "jpg", os);
- }
- catch (IOException e)
- {
- return AjaxResult.error(e.getMessage());
- }
-
- ajax.put("uuid", uuid);
- ajax.put("img", Base64.encode(os.toByteArray()));
- return ajax;
- }


vuex全局对象:

请求封装:


from:com.ruoyi.framework.web.service
- public String login(String username, String password, String code, String uuid)
- {
- // 验证码校验
- validateCaptcha(username, code, uuid);
- // 登录前置校验
- loginPreCheck(username, password);
- // 用户验证
- Authentication authentication = null;
- try
- {
- UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
- AuthenticationContextHolder.setContext(authenticationToken);
- // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
- authentication = authenticationManager.authenticate(authenticationToken);
- }
- 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());
- }
- }
- finally
- {
- AuthenticationContextHolder.clearContext();
- }
- AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
- LoginUser loginUser = (LoginUser) authentication.getPrincipal();
- recordLoginInfo(loginUser.getUserId());
- // 生成token
- return tokenService.createToken(loginUser);
- }
1.验证码校验(validateCaptcha(String username, String code, String uuid))

2.登录前置校验
- /**
- * 登录前置校验
- * @param username 用户名
- * @param password 用户密码
- */
- public void loginPreCheck(String username, String password)
- {
- // 用户名或密码为空 错误
- if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password))
- {
- AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null")));
- throw new UserNotExistsException();
- }
- // 密码如果不在指定范围内 错误
- if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
- || password.length() > UserConstants.PASSWORD_MAX_LENGTH)
- {
- AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
- throw new UserPasswordNotMatchException();
- }
- // 用户名不在指定范围内 错误
- if (username.length() < UserConstants.USERNAME_MIN_LENGTH
- || username.length() > UserConstants.USERNAME_MAX_LENGTH)
- {
- AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
- throw new UserPasswordNotMatchException();
- }
- // IP黑名单校验
- String blackStr = configService.selectConfigByKey("sys.login.blackIPList");
- if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr()))
- {
- AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("login.blocked")));
- throw new BlackListException();
- }
- }
3.用户验证并生成Token
