若依框架详细使用
Posted 一麟yl
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了若依框架详细使用相关的知识,希望对你有一定的参考价值。
目录
🏳🌈若依是用来干什么的❓
若依(ruoyi)一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。
🚩技术支持:
1.前端:Vue和ElementUI
2.后端:Spring Boot、Spring Security、Redis & JWT
3.权限认证使用jwt,支持多终端认证系统
4.支持动态加载权限菜单,多方式轻松权限控制
5.高效率开发,使用代码生成器可以一键生成前后端代码
6.数据库支持MySQL和Oracle
🏳🌈如何下载❓
🚩官网地址:
//这里我就以前后端分离版来讲解
//然后点击克隆/下载:
//可以复制链接使用git拉到本地也可以直接下载压缩包,可以根据自己的喜好来.
🏳🌈如何搭建ruoyi环境❓
//在讲解如何使用之前还是先跟大家若依框架的目录结构吧。
🚩若依框架的目录结构
//一般情况下,ruoyi-system是储存后台代码的,ruoyi-ui是储存前端代码的
//sql文件夹中是有两个sql脚本的,这两个脚本都是若依开源项目的必须脚本,需要运行在你自己 的数据库中,如果报错就交换一下两个脚本的运行顺序即可。
//在运行完两个脚本之后只需要修改若依一下配置即可运行了。
🚩 修改配置文件
1.application-druid.yml文件:
# 主库数据源
master:
url: jdbc:mysql://localhost:3306/medical?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password:
填写好自己的账号名及密码并将修改数据库的库名。
2.application.yml文件:
# 项目相关配置
ruoyi:
# 名称
name: RuoYi
# 版本
version: 3.8.4
# 版权年份
copyrightYear: 2022
# 实例演示开关
demoEnabled: true
# 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
profile: D:/ruoyi/uploadPath
# 获取ip地址开关
addressEnabled: false
# 验证码类型 math 数组计算 char 字符验证
captchaType: math
# 开发环境配置
server:
# 服务器的HTTP端口,默认为8080
port: 8080
servlet:
# 应用的访问路径
context-path: /
tomcat:
# tomcat的URI编码
uri-encoding: UTF-8
# 连接数满后的排队数,默认为100
accept-count: 1000
threads:
# tomcat最大线程数,默认为200
max: 800
# Tomcat启动初始化的线程数,默认值10
min-spare: 100
# 日志配置
logging:
level:
com.ruoyi: debug
org.springframework: warn
# 用户配置
user:
password:
# 密码最大错误次数
maxRetryCount: 5
# 密码锁定时间(默认10分钟)
lockTime: 10
# Spring配置
spring:
# 资源信息
messages:
# 国际化资源文件路径
basename: i18n/messages
profiles:
active: druid
# 文件上传
servlet:
multipart:
# 单个文件大小
max-file-size: 10MB
# 设置总上传的文件大小
max-request-size: 20MB
# 服务模块
devtools:
restart:
# 热部署开关
enabled: true
# redis 配置
redis:
# 地址
host: localhost
# 端口,默认为6379
port: 6379
# 数据库索引
database: 0
# 密码
password: 123456
# 连接超时时间
timeout: 10s
lettuce:
pool:
# 连接池中的最小空闲连接
min-idle: 0
# 连接池中的最大空闲连接
max-idle: 8
# 连接池的最大数据库连接数
max-active: 8
# #连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
# token配置
token:
# 令牌自定义标识
header: Authorization
# 令牌密钥
secret: abcdefghijklmnopqrstuvwxyz
# 令牌有效期(默认30分钟)
expireTime: 30
# MyBatis配置
mybatis:
# 搜索指定包别名
typeAliasesPackage: com.ruoyi.**.domain
# 配置mapper的扫描,找到所有的mapper.xml映射文件
mapperLocations: classpath*:mapper/**/*Mapper.xml
# 加载全局的配置文件
configLocation: classpath:mybatis/mybatis-config.xml
# PageHelper分页插件
pagehelper:
helperDialect: mysql
supportMethodsArguments: true
params: count=countSql
# Swagger配置
swagger:
# 是否开启swagger
enabled: true
# 请求前缀
pathMapping: /dev-api
# 防止XSS攻击
xss:
# 过滤开关
enabled: true
# 排除链接(多个用逗号分隔)
excludes: /system/notice
# 匹配链接
urlPatterns: /system/*,/monitor/*,/tool/*
这个文件是若依框架的主配置文件 ,主要有一下相关配置:
①ruoyi:这里是关于你这个项目的基本信息,里面有一个是验证码的形式(主要有数字个字符两种形式,可以自行选择,当然如果你不想要验证码也可以去数据库中找到sys_config这个配置表将其关闭如下图所示👇)
②server:这里是开发环境的设置,修改后台端口号就是在这个地方,一般情况下也不需要动这个地方除非默认的8080端口被占用了
③logging:这里是日志的显示形式,默认是debug的形式
④user:用户配置
⑤spring:里面有一个redis是需要修改地址和密码的,端口号一般情况下是默认的,redis这里有两种使用方式,一个是远程的,一个是本地的,这里建议是使用本地的,因为远程的服务不稳定需要考虑网络因素,有时就是因为一个redis项目卡在那就是因为这个原因,这里值得一提的是安装redis的时候不要装错了,比如说我的就是Windows的,就装Windows就行了,下面是redis官网。
⑥token:令牌的配置
⑦pagehelper:分页插件的配置
⑧swagger:swagger框架的配置
⑨xss:防止跨站脚本攻击的配置
🚩运行后台服务
运行RuoYiApplication这个启动程序,类路径如下:
ruoyi-admin模板->>src/main/java->>com.ruoyi->>RuoYiApplication
//若成功打印了下面的样图就表示后台运行成功:
//若没有成功请检查上述步骤是否有遗漏.
🚩运行前台服务
1.在ruoyi-ui模板下打开命令指示符
输入npm install初始化前端项目
2.输入npm run dev运行项目
//运行成功后会自动跳转至浏览器.
//进行到这个地方前期的准备工作就已经完成了
🏳🌈如何使用❓
✨登陆成功之后就会显示如下界面:
接下来主要讲解若依框架的菜单管理和数据字典以及代码生成。
🚩菜单生成的使用
//菜单的生成其实就是在sys_menu这张若依系统表中做操作的:
如何新增菜单?
点击新增 👇
目录的创建:
- 上级菜单:其实就是父级菜单,对应数据库表字段中的parent_id,如果没有父级菜单就会默认为0
- 菜单名称:显示在左侧的菜单名
- 显示排序:自上而下显示的顺序
- 路由地址:点击此菜单或者此目录跳转的路径(根据自己的需要来,不要乱来)
- 是否外链:是否需要跳转至http(s)下的路由地址,一般情况下不需要选,除非你真的想要跳转外站地址(根据自己的需要来)
- 显示状态:隐藏就是不会显示菜单在左侧,但是任然可以跳转菜单及菜单下的路由地址
- 菜单状态:这里的状态禁用了除了不会显示在左侧菜单之外,还不能跳转到该菜单及菜单下的路由地址
菜单的创建:
//可以看出来菜单相比较目录而言就多了几个选项,下面来说说这些选项时用来干嘛的
1.组件路径:其实就是前端代码中的组件存放的地址如下图所示:
用户管理的组件路径是system/user/index
其实就是在本地中对应的就是ruoyi-ui下src目录下的view文件下的地址
注意:这里的组件路径如果与你本地的文件路径不一致就会导致你点击了这个菜单但是并没有跳转到指定的地方,其实说白了就是404异常。
2.权限字符:控制器中定义的权限字符,如:@PreAuthorize(`@ss.hasPermi('system:user:list')`)这里的权限字符可以定义在菜单上也能定义在按钮上用来细化权限
3.路由参数:访问路由时需要携带的参数,这里需要注意是,需要写成对象并以键值对的形式保存,如name:"zs",sex:"男"
4.是否缓存:这里需要注意的是开启缓存的前提是组件的“name”必须与路由保持一致,因为若依是使用vue的一个抽象组件库keep-alive来处理缓存的
按钮的创建:
一般情况下我们是不会在这个地方创建按钮的,因为代码生成的时候若依会自动创建按钮,并且本人也不建议在这里创建按钮,因为本身我们使用若依框架就是为了快速开发,很多操作没必要化简为繁
🚩数据字典的使用
1.字典的创建:
- 字典名称:其实就是这个字典的标签,如用户性别
- 字典类型:这里需要注意的是在定义类型的时候不能乱来,这里定义的类型不能与已经有的类型重复,否则会报冲突异常,并且在定义类型的时候要有一定的规范,如果你不想定义的太复杂,这里建议使用(表名+字段) ,如用户性别sys_user表中的性别sex,写成sys_user_sex就行了
2.字典数值插入
//点击字典类型然后再点击新增:
- 数据标签:显示出来内容,如用户性别中的“男”
- 数据键值:保存在数据库中的int值,如1
- 排序顺序:显示的先后顺序
🚩代码生成的使用
//这里我以用户表为例
1.导入表结构
点击导入选择需要导入的表结构
2.编辑需要生成的信息
选中该表点击右边的编辑
基本信息、字段信息、生成信息三者根据自己的需求来编辑
如果要使用数据字典就直接在字段信息里面选择就行了,如下图
//在编辑生成信息的时候,可以选择上级菜单,这里就能够选择自己生成的菜单来处理业务,若依会帮你把路由都配置好的。
生成代码的方式:
这里生成的方式主要有两种(其实就是下载的方式):
1.压缩包的形式:一般情况下是使用这种形式,毕竟也方便,下载完之后直接解压放到项目指定的文件目录即可使用
2.自定义地址:如果自定义了自己的模块为了避免不必要的麻烦建议使用自定义地址
3.如何将下载的代码导入到项目中?
//这里我就直接讲解压缩包形式的,因为另一个是一样的方式。
上图就是下载之后的文件
1.sql文件就是你在生成代码的时候编辑的菜单及按钮,需要运行在你的数据库中
2.vue文件里面存放的是前端的代码里面有两个文件夹,api是js文件,views是vue文件,放入项目中对应的文件目录即可,如果没有冲突文件可以直接覆盖
3.main里面存放的就是后端的代码,操作同上述
注意:
在生成代码的时候如果数据库中存在相同字段比如说:多张表出现status字段,就会导致,在生成代码的时候有些实体类中字段缺失,明明这个实体类应该有这个字段但是生成之后的代码却没有,但是也不报错,导致这个问题是因为,若依生成的get/set方法使用的修饰符都是public,这个就会导致你在生成的时候默认你已经有get/set方法,就不会再帮你生成get/set方法,解决方式有两种:第一种就是从本源出发修改数据库中的字段,第二种就是手动添加实体类中的字段。
关于若依框架的就讲解到这里了,有什么问题欢迎私信博主!😂
若依(RuoYi)SpringBoot框架密码加密传输(前后分离板)
运行环境:
Java 版本 1.8
Spring Boot 版本: 2.2.13.RELEASE
目前登录接口密码是明文传输 为了更高安全性 我准备调整为加密方式传输( 这里选择Rsa加密算法) 并分享下编写过程
更改前
更改后
大概加密流程:
- 后台生成随机公钥私钥
- 前台拿到公钥集成jsencrypt实现密码加密
- 传输加密后的密码给后台
- 后台通过私钥对加密后的密码进行解密
若依详细登陆流程<<<可以看这里
若依官方的加密方法<<<原本是固定公私秘钥 我改为了随机生成
篇幅过长『请』耐心看完哦?? 有什么问题可以联系我~
目录
后台改动
首先新建RsaUtils类
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
@Component
public class RsaUtils
// Rsa 私钥 也可固定秘钥对 若依原写法(不安全)
public static String privateKeys = "";
private static String publicKeyStr = "";
private static String privateKeyStr = "";
private static final RsaKeyPair rsaKeyPair = new RsaKeyPair();
private static final Logger logger = LoggerFactory.getLogger(MapUtils.class);
/**
* 私钥解密
*
* @param text 待解密的文本
* @return 解密后的文本
*/
public static String decryptByPrivateKey(String text) throws Exception
// logger.info(rsaKeyPair.getPrivateKey());
return decryptByPrivateKey(rsaKeyPair.getPrivateKey(), text);
/**
* 公钥解密
*
* @param publicKeyString 公钥
* @param text 待解密的信息
* @return 解密后的文本
*/
public static String decryptByPublicKey(String publicKeyString, String text) throws Exception
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyString));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, publicKey);
byte[] result = cipher.doFinal(Base64.decodeBase64(text));
return new String(result);
/**
* 私钥加密
*
* @param privateKeyString 私钥
* @param text 待加密的信息
* @return 加密后的文本
*/
public static String encryptByPrivateKey(String privateKeyString, String text) throws Exception
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyString));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] result = cipher.doFinal(text.getBytes());
return Base64.encodeBase64String(result);
/**
* 私钥解密
*
* @param privateKeyString 私钥
* @param text 待解密的文本
* @return 解密后的文本
*/
public static String decryptByPrivateKey(String privateKeyString, String text) throws Exception
PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyString));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec5);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] result = cipher.doFinal(Base64.decodeBase64(text));
return new String(result);
/**
* 公钥加密
*
* @param publicKeyString 公钥
* @param text 待加密的文本
* @return 加密后的文本
*/
public static String encryptByPublicKey(String publicKeyString, String text) throws Exception
X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyString));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec2);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] result = cipher.doFinal(text.getBytes());
return Base64.encodeBase64String(result);
/**
* 构建RSA密钥对
*
* @return 生成后的公私钥信息
*/
@Bean
public void generateKeyPair() throws NoSuchAlgorithmException, NoSuchProviderException
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(1024);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
String publicKeyString = Base64.encodeBase64String(rsaPublicKey.getEncoded());
String privateKeyString = Base64.encodeBase64String(rsaPrivateKey.getEncoded());
rsaKeyPair.setPrivateKey(privateKeyString);
rsaKeyPair.setPublicKey(publicKeyString);
publicKeyStr = publicKeyString;
privateKeyStr = privateKeyString;
public static String getPublicKey()
return publicKeyStr;
public static String getPrivateKey()
return privateKeyStr;
public static RsaKeyPair rsaKeyPair()
return rsaKeyPair;
/**
* RSA密钥对对象
*/
public static class RsaKeyPair
private String publicKey;
private String privateKey;
public void setPublicKey(String publicKey)
this.publicKey = publicKey;
public void setPrivateKey(String privateKey)
this.privateKey = privateKey;
public RsaKeyPair()
public RsaKeyPair(String publicKey, String privateKey)
this.publicKey = publicKey;
this.privateKey = privateKey;
public String getPublicKey()
return publicKey;
public String getPrivateKey()
return privateKey;
RsaUtils添加了@Component注解 generateKeyPair()构建密钥对添加了@Bean注解 在项目启动时通过@Bean的方式将普通类事例化到spring容器中 所以在系统启动后 每次调用接口会是一样的公私秘钥 每次重启后公私钥不同
在controller层添加获取公钥接口
/**
* 获取公钥 前端用来密码加密
*
* @return
*/
@GetMapping("/publicKey")
public RsaUtils.RsaKeyPair publicKey()
//便于测试 公私秘钥都传了 可改为只传公钥
//RsaUtils.RsaKeyPair rsaKeyPair = new RsaUtils.RsaKeyPair();
//rsaKeyPair.setPublicKey(RsaUtils.getPublicKey());
//return rsaKeyPair;
return RsaUtils.rsaKeyPair();
登录方法SysLoginService类修改(重点)
测试内部会调用authenticationManager.authenticate()对账号和密码做验证 具体细节推荐看原代码
最终会调用UserDetailsServiceImpl.loadUserByUsername()方法 若依重写了此方法
authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, RsaUtils.decryptByPrivateKey(password)));
重置密码接口要也需要更改!!不要忘记啦
/**
* 重置密码
*/
@Log(title = "个人信息", businessType = BusinessType.UPDATE)
@PutMapping("/updatePwd")
public AjaxResult updatePwd(String oldPassword, String newPassword) throws Exception
LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
String userName = loginUser.getUsername();
//加密后的
String password = loginUser.getPassword();
//解密
oldPassword = RsaUtils.decryptByPrivateKey(oldPassword);
newPassword = RsaUtils.decryptByPrivateKey(newPassword);
//拿原密码和加密后的解密
if (!SecurityUtils.matchesPassword(oldPassword, password))
return AjaxResult.error("修改密码失败,旧密码错误");
if (SecurityUtils.matchesPassword(newPassword, password))
return AjaxResult.error("新密码不能与旧密码相同");
if (userService.resetUserPwd(userName, SecurityUtils.encryptPassword(newPassword)) > 0)
// 更新缓存用户密码
loginUser.getUser().setPassword(SecurityUtils.encryptPassword(newPassword));
tokenService.setLoginUser(loginUser);
return AjaxResult.success();
return AjaxResult.error("修改密码异常,请联系管理员");
最后在SecurityConfig类里添加白名单
/**
* anonymous() 允许匿名用户访问,不允许已登入用户访问
* permitAll() 不管登入,不登入 都能访问
*/
.antMatchers("/publicKey").permitAll()
anonymous()和permitAll()权限是个坑 大家注意
至此后台工作已完成 挪步前端(没错 前后端都是我写的??)
前端改动
login.js添加获取公钥接口路径
// 获取key
export function getPublicKey()
return request(
url: '/publicKey',
method: 'get',
)
user.js更改登陆方法
actions:
getPublicKey()
return new Promise((resolve, reject) =>
getPublicKey()
.then(res =>
resolve(res)
)
.catch(error =>
reject(error)
)
)
,
// 登录
Login( commit, dispatch , userInfo)
return new Promise((resolve, reject) =>
dispatch('getPublicKey').then(res =>
let publicKey = res.publicKey
const username = userInfo.username.trim()
//调用加密方法(传密码和公钥)
const password = encrypt(userInfo.password, publicKey)
const code = userInfo.code
const uuid = userInfo.uuid
login(username, password, code, uuid)
.then(res =>
setToken(res.token)
commit('SET_TOKEN', res.token)
resolve()
)
.catch(error =>
reject(error)
)
)
)
,
resetPwd.vue更改修改密码的页面
methods:
getPublicKey()
return new Promise((resolve, reject) =>
getPublicKey()
.then(res =>
resolve(res)
)
.catch(error =>
reject(error)
)
)
,
submit()
this.$refs["form"].validate(valid =>
if (valid)
this.getPublicKey().then(res=>
let publicKey = res.publicKey
console.log("res.publicKey",res.publicKey)
const oldPassword = encrypt(this.user.oldPassword, publicKey)
const newPassword = encrypt(this.user.newPassword, publicKey)
updateUserPwd(oldPassword, newPassword).then(
response =>
this.msgSuccess("修改成功");
);
)
);
,
close()
this.$store.dispatch("tagsView/delView", this.$route);
this.$router.push( path: "/index" );
JSEncrypt.js更改加解密方法
import JSEncrypt from 'jsencrypt/bin/jsencrypt.min'
// 密钥对生成 http://web.chacuo.net/netrsakeypair
//这里注掉了原来固定的公私钥
//const publicKey = ''
//const privateKey = ''
// 加密
export function encrypt(txt, publicKey)
const encryptor = new JSEncrypt()
encryptor.setPublicKey(publicKey) // 设置公钥
return encryptor.encrypt(txt) // 对数据
// 解密(暂无使用)
export function decrypt(txt)
const encryptor = new JSEncrypt()
encryptor.setPrivateKey(privateKey) // 设置私钥
return encryptor.decrypt(txt) // 对数据进行解密
登陆验证下吧~
有问题欢迎留言讨论??
先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦
以上是关于若依框架详细使用的主要内容,如果未能解决你的问题,请参考以下文章