前言
由于最近做项目需要基于若依框架(前后端分离版)二次开发,这里简单记录一下我看若依框架源代码的过程,供自己复习时使用,也希望能够给想学习若依框架的朋友一点启发!
若依项目代码运行前需要配置MySQL和Redis
若依的前端代码主要集中在ruoyi-ui模块的src/views目录下
若依的后端代码主要集中在ruoyi-admin模块
验证码模块
验证码生成的主要步骤:
- 后端生成一个表达式,如 4-2=2
- 实际上是 4-2=?@2
- 1+1=? 转成图片,2存入Redis
前端代码
从登录界面的代码入手,找到验证码部分。
我们刷新登录页面,通过浏览器F12,可以看到请求的URL,如下图所示。
由上图可见,captchaImage
请求有个统一前缀dev-api
,并且请求的是localhost:80
(没加端口号,默认80),也就是请求的是前端。这其实是为了解决跨域问题,若依是在前端通过反向代理来解决的,URL请求前端,然后再映射到后端,具体配置见vue.config.js
文件。
后端代码
利用idea的全局搜索功能(如下图所示,快捷键是Ctrl+Shift+R
),搜索刚刚前端看到的captchaImage
。
/**
* 生成验证码
*/
@GetMapping("/captchaImage")
public AjaxResult getCode(HttpServletResponse response) throws IOException
{
AjaxResult ajax = AjaxResult.success();
boolean captchaOnOff = configService.selectCaptchaOnOff();
ajax.put("captchaOnOff", captchaOnOff);
if (!captchaOnOff)
{
return ajax;
}
// 保存验证码信息
String uuid = IdUtils.simpleUUID();
String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
String capStr = null, code = null;
BufferedImage image = null;
// 生成验证码
String captchaType = RuoYiConfig.getCaptchaType();
if ("math".equals(captchaType))
{
String capText = captchaProducerMath.createText(); // 4-2=?@2
capStr = capText.substring(0, capText.lastIndexOf("@")); // 4-2=?
code = capText.substring(capText.lastIndexOf("@") + 1); // 2
image = captchaProducerMath.createImage(capStr); // 生成的表达式图片
}
else if ("char".equals(captchaType))
{
capStr = code = captchaProducer.createText();
image = captchaProducer.createImage(capStr);
}
// verifyKey——captcha_codes:077e4780a55c406e852669df581f1763
// code——表达式答案,也就是2
// Constants.CAPTCHA_EXPIRATION+TimeUnit.MINUTES——验证码超时时间,这里是两分钟
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;
}
若依将后端响应给前端的数据封装成一个AjaxResult
对象(继承自HashMap),对象结构如下图所示。
RDM查看Redis中的键值对:
- key——统一前缀:uuid
- value——2(表达式答案)
- ttl:键值对超时剩余时间
登录模块
登录主要步骤:
-
校验验证码
-
校验用户名密码
-
生成Token令牌
前端代码流程与验证码模块类似,这里就不再赘述了,直接看后端代码。
后端代码
通过浏览器查看点击登录按钮后请求的URL。
可以看到,点击登录按钮后一共发送了3个请求:
- login:验证登录信息
- getInfo:获取当前用户的角色和权限信息,存储在Vuex中
- getRouters:根据当前用户的权限获取动态路由
先来看看login,全局搜索‘/login’,获取代码位置。
双击进入。
ctrl + 鼠标左键,进入到loginService的login方法,可以看到登录的具体流程,如下图所示:
校验验证码的流程:
Mapper中的sql不方便查看,这里如果想看底层最终执行的的sql语句的话,可以再对应的mapper方法处打一个断点,接着清空控制台,然后放开断点,就能看到执行的sql语句了。
Redis中保存的已登录用户的会话信息