mirror of
https://github.com/dromara/RuoYi-Vue-Plus.git
synced 2025-09-24 07:19:46 +08:00
Merge branch '5.X' of https://gitee.com/dromara/RuoYi-Vue-Plus into JustAuth
# Conflicts: # ruoyi-admin/src/main/resources/application-dev.yml
This commit is contained in:
@ -14,11 +14,12 @@ import org.dromara.common.core.utils.reflect.ReflectUtils;
|
||||
import org.dromara.common.mail.config.properties.MailProperties;
|
||||
import org.dromara.common.mail.utils.MailUtils;
|
||||
import org.dromara.common.redis.utils.RedisUtils;
|
||||
import org.dromara.common.sms.config.properties.SmsProperties;
|
||||
import org.dromara.common.sms.core.SmsTemplate;
|
||||
import org.dromara.common.sms.entity.SmsResult;
|
||||
import org.dromara.common.web.config.properties.CaptchaProperties;
|
||||
import org.dromara.common.web.enums.CaptchaType;
|
||||
import org.dromara.sms4j.api.SmsBlend;
|
||||
import org.dromara.sms4j.api.entity.SmsResponse;
|
||||
import org.dromara.sms4j.core.factory.SmsFactory;
|
||||
import org.dromara.sms4j.provider.enumerate.SupplierType;
|
||||
import org.dromara.web.domain.vo.CaptchaVo;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@ -31,8 +32,7 @@ import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
/**
|
||||
* 验证码操作处理
|
||||
@ -47,7 +47,6 @@ import java.util.Map;
|
||||
public class CaptchaController {
|
||||
|
||||
private final CaptchaProperties captchaProperties;
|
||||
private final SmsProperties smsProperties;
|
||||
private final MailProperties mailProperties;
|
||||
|
||||
/**
|
||||
@ -57,21 +56,18 @@ public class CaptchaController {
|
||||
*/
|
||||
@GetMapping("/resource/sms/code")
|
||||
public R<Void> smsCode(@NotBlank(message = "{user.phonenumber.not.blank}") String phonenumber) {
|
||||
if (!smsProperties.getEnabled()) {
|
||||
return R.fail("当前系统没有开启短信功能!");
|
||||
}
|
||||
String key = GlobalConstants.CAPTCHA_CODE_KEY + phonenumber;
|
||||
String code = RandomUtil.randomNumbers(4);
|
||||
RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
|
||||
// 验证码模板id 自行处理 (查数据库或写死均可)
|
||||
String templateId = "";
|
||||
Map<String, String> map = new HashMap<>(1);
|
||||
LinkedHashMap<String, String> map = new LinkedHashMap<>(1);
|
||||
map.put("code", code);
|
||||
SmsTemplate smsTemplate = SpringUtils.getBean(SmsTemplate.class);
|
||||
SmsResult result = smsTemplate.send(phonenumber, templateId, map);
|
||||
if (!result.isSuccess()) {
|
||||
log.error("验证码短信发送异常 => {}", result);
|
||||
return R.fail(result.getMessage());
|
||||
SmsBlend smsBlend = SmsFactory.createSmsBlend(SupplierType.ALIBABA);
|
||||
SmsResponse smsResponse = smsBlend.sendMessage(phonenumber, templateId, map);
|
||||
if (!"OK".equals(smsResponse.getCode())) {
|
||||
log.error("验证码短信发送异常 => {}", smsResponse);
|
||||
return R.fail(smsResponse.getMessage());
|
||||
}
|
||||
return R.ok();
|
||||
}
|
||||
|
@ -345,7 +345,7 @@ public class SysLoginService {
|
||||
|
||||
private SysUserVo loadUserByEmail(String tenantId, String email) {
|
||||
SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
|
||||
.select(SysUser::getPhonenumber, SysUser::getStatus)
|
||||
.select(SysUser::getEmail, SysUser::getStatus)
|
||||
.eq(TenantHelper.isEnable(), SysUser::getTenantId, tenantId)
|
||||
.eq(SysUser::getEmail, email));
|
||||
if (ObjectUtil.isNull(user)) {
|
||||
@ -414,25 +414,24 @@ public class SysLoginService {
|
||||
String errorKey = GlobalConstants.PWD_ERR_CNT_KEY + username;
|
||||
String loginFail = Constants.LOGIN_FAIL;
|
||||
|
||||
// 获取用户登录错误次数(可自定义限制策略 例如: key + username + ip)
|
||||
Integer errorNumber = RedisUtils.getCacheObject(errorKey);
|
||||
// 获取用户登录错误次数,默认为0 (可自定义限制策略 例如: key + username + ip)
|
||||
int errorNumber = ObjectUtil.defaultIfNull(RedisUtils.getCacheObject(errorKey), 0);
|
||||
// 锁定时间内登录 则踢出
|
||||
if (ObjectUtil.isNotNull(errorNumber) && errorNumber.equals(maxRetryCount)) {
|
||||
if (errorNumber >= maxRetryCount) {
|
||||
recordLogininfor(tenantId, username, loginFail, MessageUtils.message(loginType.getRetryLimitExceed(), maxRetryCount, lockTime));
|
||||
throw new UserException(loginType.getRetryLimitExceed(), maxRetryCount, lockTime);
|
||||
}
|
||||
|
||||
if (supplier.get()) {
|
||||
// 是否第一次
|
||||
errorNumber = ObjectUtil.isNull(errorNumber) ? 1 : errorNumber + 1;
|
||||
// 错误次数递增
|
||||
errorNumber++;
|
||||
RedisUtils.setCacheObject(errorKey, errorNumber, Duration.ofMinutes(lockTime));
|
||||
// 达到规定错误次数 则锁定登录
|
||||
if (errorNumber.equals(maxRetryCount)) {
|
||||
RedisUtils.setCacheObject(errorKey, errorNumber, Duration.ofMinutes(lockTime));
|
||||
if (errorNumber >= maxRetryCount) {
|
||||
recordLogininfor(tenantId, username, loginFail, MessageUtils.message(loginType.getRetryLimitExceed(), maxRetryCount, lockTime));
|
||||
throw new UserException(loginType.getRetryLimitExceed(), maxRetryCount, lockTime);
|
||||
} else {
|
||||
// 未达到规定错误次数 则递增
|
||||
RedisUtils.setCacheObject(errorKey, errorNumber);
|
||||
// 未达到规定错误次数
|
||||
recordLogininfor(tenantId, username, loginFail, MessageUtils.message(loginType.getRetryLimitCount(), errorNumber));
|
||||
throw new UserException(loginType.getRetryLimitCount(), errorNumber);
|
||||
}
|
||||
|
@ -158,162 +158,29 @@ mail:
|
||||
# Socket连接超时值,单位毫秒,缺省值不超时
|
||||
connectionTimeout: 0
|
||||
|
||||
--- # sms 短信
|
||||
--- # sms 短信 支持 阿里云 腾讯云 云片 等等各式各样的短信服务商
|
||||
# https://wind.kim/doc/start 文档地址 各个厂商可同时使用
|
||||
sms:
|
||||
enabled: false
|
||||
# 阿里云 dysmsapi.aliyuncs.com
|
||||
# 腾讯云 sms.tencentcloudapi.com
|
||||
endpoint: "dysmsapi.aliyuncs.com"
|
||||
accessKeyId: xxxxxxx
|
||||
accessKeySecret: xxxxxx
|
||||
signName: 测试
|
||||
# 腾讯专用
|
||||
sdkAppId:
|
||||
|
||||
justauth:
|
||||
enabled: true
|
||||
type:
|
||||
QQ:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: http://oauth.xkcoding.com/demo/oauth/qq/callback
|
||||
union-id: false
|
||||
WEIBO:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: http://oauth.xkcoding.com/demo/oauth/weibo/callback
|
||||
gitee:
|
||||
client-id: 38eaaa1b77b5e064313057a2f5745ce3a9f3e7686d9bd302c7df2f308ef6db81
|
||||
client-secret: 2e633af8780cb9fe002c4c7291b722db944402e271efb99b062811f52d7da1ff
|
||||
redirect-uri: http://localhost:8888/social-login?source=gitee
|
||||
DINGTALK:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: http://oauth.xkcoding.com/demo/oauth/dingtalk/callback
|
||||
BAIDU:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: http://oauth.xkcoding.com/demo/oauth/baidu/callback
|
||||
CSDN:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: http://oauth.xkcoding.com/demo/oauth/csdn/callback
|
||||
CODING:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: http://oauth.xkcoding.com/demo/oauth/coding/callback
|
||||
coding-group-name: xx
|
||||
OSCHINA:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: http://oauth.xkcoding.com/demo/oauth/oschina/callback
|
||||
ALIPAY:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: http://oauth.xkcoding.com/demo/oauth/alipay/callback
|
||||
alipay-public-key: MIIB**************DAQAB
|
||||
WECHAT_OPEN:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: http://oauth.xkcoding.com/demo/oauth/wechat_open/callback
|
||||
WECHAT_MP:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: http://oauth.xkcoding.com/demo/oauth/wechat_mp/callback
|
||||
WECHAT_ENTERPRISE:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: http://oauth.xkcoding.com/demo/oauth/wechat_enterprise/callback
|
||||
agent-id: 1000002
|
||||
TAOBAO:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: http://oauth.xkcoding.com/demo/oauth/taobao/callback
|
||||
GOOGLE:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: http://oauth.xkcoding.com/demo/oauth/google/callback
|
||||
FACEBOOK:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: http://oauth.xkcoding.com/demo/oauth/facebook/callback
|
||||
DOUYIN:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: http://oauth.xkcoding.com/demo/oauth/douyin/callback
|
||||
LINKEDIN:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: http://oauth.xkcoding.com/demo/oauth/linkedin/callback
|
||||
MICROSOFT:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: http://oauth.xkcoding.com/demo/oauth/microsoft/callback
|
||||
MI:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: http://oauth.xkcoding.com/demo/oauth/mi/callback
|
||||
TOUTIAO:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: http://oauth.xkcoding.com/demo/oauth/toutiao/callback
|
||||
TEAMBITION:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: http://oauth.xkcoding.com/demo/oauth/teambition/callback
|
||||
RENREN:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: http://oauth.xkcoding.com/demo/oauth/renren/callback
|
||||
PINTEREST:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: http://oauth.xkcoding.com/demo/oauth/pinterest/callback
|
||||
STACK_OVERFLOW:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: http://oauth.xkcoding.com/demo/oauth/stack_overflow/callback
|
||||
stack-overflow-key: asd*********asd
|
||||
HUAWEI:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: http://oauth.xkcoding.com/demo/oauth/huawei/callback
|
||||
KUJIALE:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: http://oauth.xkcoding.com/demo/oauth/kujiale/callback
|
||||
GITLAB:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: http://oauth.xkcoding.com/demo/oauth/gitlab/callback
|
||||
MEITUAN:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: http://oauth.xkcoding.com/demo/oauth/meituan/callback
|
||||
ELEME:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: http://oauth.xkcoding.com/demo/oauth/eleme/callback
|
||||
TWITTER:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: http://oauth.xkcoding.com/demo/oauth/twitter/callback
|
||||
XMLY:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: http://oauth.xkcoding.com/demo/oauth/xmly/callback
|
||||
# 设备唯一标识ID
|
||||
device-id: xxxxxxxxxxxxxx
|
||||
# 客户端操作系统类型,1-iOS系统,2-Android系统,3-Web
|
||||
client-os-type: 3
|
||||
# 客户端包名,如果 clientOsType 为1或2时必填。对Android客户端是包名,对IOS客户端是Bundle ID
|
||||
#pack-id: xxxx
|
||||
FEISHU:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: http://oauth.xkcoding.com/demo/oauth/feishu/callback
|
||||
JD:
|
||||
client-id: 10**********6
|
||||
client-secret: 1f7d08**********5b7**********29e
|
||||
redirect-uri: http://oauth.xkcoding.com/demo/oauth/jd/callback
|
||||
|
||||
alibaba:
|
||||
#请求地址 默认为 dysmsapi.aliyuncs.com 如无特殊改变可以不用设置
|
||||
requestUrl: dysmsapi.aliyuncs.com
|
||||
#阿里云的accessKey
|
||||
accessKeyId: xxxxxxx
|
||||
#阿里云的accessKeySecret
|
||||
accessKeySecret: xxxxxxx
|
||||
#短信签名
|
||||
signature: 测试
|
||||
tencent:
|
||||
#请求地址默认为 sms.tencentcloudapi.com 如无特殊改变可不用设置
|
||||
requestUrl: sms.tencentcloudapi.com
|
||||
#腾讯云的accessKey
|
||||
accessKeyId: xxxxxxx
|
||||
#腾讯云的accessKeySecret
|
||||
accessKeySecret: xxxxxxx
|
||||
#短信签名
|
||||
signature: 测试
|
||||
#短信sdkAppId
|
||||
sdkAppId: appid
|
||||
#地域信息默认为 ap-guangzhou 如无特殊改变可不用设置
|
||||
territory: ap-guangzhou
|
||||
|
@ -161,14 +161,29 @@ mail:
|
||||
# Socket连接超时值,单位毫秒,缺省值不超时
|
||||
connectionTimeout: 0
|
||||
|
||||
--- # sms 短信
|
||||
--- # sms 短信 支持 阿里云 腾讯云 云片 等等各式各样的短信服务商
|
||||
# https://wind.kim/doc/start 文档地址 各个厂商可同时使用
|
||||
sms:
|
||||
enabled: false
|
||||
# 阿里云 dysmsapi.aliyuncs.com
|
||||
# 腾讯云 sms.tencentcloudapi.com
|
||||
endpoint: "dysmsapi.aliyuncs.com"
|
||||
accessKeyId: xxxxxxx
|
||||
accessKeySecret: xxxxxx
|
||||
signName: 测试
|
||||
# 腾讯专用
|
||||
sdkAppId:
|
||||
alibaba:
|
||||
#请求地址 默认为 dysmsapi.aliyuncs.com 如无特殊改变可以不用设置
|
||||
requestUrl: dysmsapi.aliyuncs.com
|
||||
#阿里云的accessKey
|
||||
accessKeyId: xxxxxxx
|
||||
#阿里云的accessKeySecret
|
||||
accessKeySecret: xxxxxxx
|
||||
#短信签名
|
||||
signature: 测试
|
||||
tencent:
|
||||
#请求地址默认为 sms.tencentcloudapi.com 如无特殊改变可不用设置
|
||||
requestUrl: sms.tencentcloudapi.com
|
||||
#腾讯云的accessKey
|
||||
accessKeyId: xxxxxxx
|
||||
#腾讯云的accessKeySecret
|
||||
accessKeySecret: xxxxxxx
|
||||
#短信签名
|
||||
signature: 测试
|
||||
#短信sdkAppId
|
||||
sdkAppId: appid
|
||||
#地域信息默认为 ap-guangzhou 如无特殊改变可不用设置
|
||||
territory: ap-guangzhou
|
||||
|
@ -96,20 +96,14 @@ spring:
|
||||
sa-token:
|
||||
# token名称 (同时也是cookie名称)
|
||||
token-name: Authorization
|
||||
# token有效期 设为一天 (必定过期) 单位: 秒
|
||||
timeout: 86400
|
||||
# token临时有效期 (指定时间无操作就过期) 单位: 秒
|
||||
# token固定超时 设为七天 (必定过期) 单位: 秒
|
||||
timeout: 604800
|
||||
# token活跃超时时间 30分钟(指定时间无操作则过期) 单位: 秒
|
||||
activity-timeout: 1800
|
||||
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
|
||||
is-concurrent: true
|
||||
# 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
|
||||
is-share: false
|
||||
# 是否尝试从header里读取token
|
||||
is-read-header: true
|
||||
# 是否尝试从cookie里读取token
|
||||
is-read-cookie: false
|
||||
# token前缀
|
||||
token-prefix: "Bearer"
|
||||
# jwt秘钥
|
||||
jwt-secret-key: abcdefghijklmnopqrstuvwxyz
|
||||
|
||||
@ -156,39 +150,12 @@ mybatis-plus:
|
||||
mapperLocations: classpath*:mapper/**/*Mapper.xml
|
||||
# 实体扫描,多个package用逗号或者分号分隔
|
||||
typeAliasesPackage: org.dromara.**.domain
|
||||
# 启动时是否检查 MyBatis XML 文件的存在,默认不检查
|
||||
checkConfigLocation: false
|
||||
configuration:
|
||||
# 自动驼峰命名规则(camel case)映射
|
||||
mapUnderscoreToCamelCase: true
|
||||
# MyBatis 自动映射策略
|
||||
# NONE:不启用 PARTIAL:只对非嵌套 resultMap 自动映射 FULL:对所有 resultMap 自动映射
|
||||
autoMappingBehavior: FULL
|
||||
# MyBatis 自动映射时未知列或未知属性处理策
|
||||
# NONE:不做处理 WARNING:打印相关警告 FAILING:抛出异常和详细信息
|
||||
autoMappingUnknownColumnBehavior: NONE
|
||||
# 更详细的日志输出 会有性能损耗 org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
# 关闭日志记录 (可单纯使用 p6spy 分析) org.apache.ibatis.logging.nologging.NoLoggingImpl
|
||||
# 默认日志输出 org.apache.ibatis.logging.slf4j.Slf4jImpl
|
||||
logImpl: org.apache.ibatis.logging.nologging.NoLoggingImpl
|
||||
global-config:
|
||||
# 是否打印 Logo banner
|
||||
banner: true
|
||||
dbConfig:
|
||||
# 主键类型
|
||||
# AUTO 自增 NONE 空 INPUT 用户输入 ASSIGN_ID 雪花 ASSIGN_UUID 唯一 UUID
|
||||
# 如需改为自增 需要将数据库表全部设置为自增
|
||||
idType: ASSIGN_ID
|
||||
# 逻辑已删除值
|
||||
logicDeleteValue: 2
|
||||
# 逻辑未删除值
|
||||
logicNotDeleteValue: 0
|
||||
# 字段验证策略之 insert,在 insert 的时候的字段验证策略
|
||||
# IGNORED 忽略 NOT_NULL 非NULL NOT_EMPTY 非空 DEFAULT 默认 NEVER 不加入 SQL
|
||||
insertStrategy: NOT_NULL
|
||||
# 字段验证策略之 update,在 update 的时候的字段验证策略
|
||||
updateStrategy: NOT_NULL
|
||||
# 字段验证策略之 select,在 select 的时候的字段验证策略既 wrapper 根据内部 entity 生成的 where 条件
|
||||
where-strategy: NOT_NULL
|
||||
|
||||
# 数据加密
|
||||
mybatis-encryptor:
|
||||
@ -204,8 +171,13 @@ mybatis-encryptor:
|
||||
publicKey:
|
||||
privateKey:
|
||||
|
||||
# Swagger配置
|
||||
swagger:
|
||||
springdoc:
|
||||
api-docs:
|
||||
# 是否开启接口文档
|
||||
enabled: true
|
||||
swagger-ui:
|
||||
# 持久化认证数据
|
||||
persistAuthorization: true
|
||||
info:
|
||||
# 标题
|
||||
title: '标题:${ruoyi.name}多租户管理系统_接口文档'
|
||||
@ -225,14 +197,6 @@ swagger:
|
||||
type: APIKEY
|
||||
in: HEADER
|
||||
name: ${sa-token.token-name}
|
||||
|
||||
springdoc:
|
||||
api-docs:
|
||||
# 是否开启接口文档
|
||||
enabled: true
|
||||
swagger-ui:
|
||||
# 持久化认证数据
|
||||
persistAuthorization: true
|
||||
#这里定义了两个分组,可定义多个,也可以不定义
|
||||
group-configs:
|
||||
- group: 1.演示模块
|
||||
|
Reference in New Issue
Block a user