From 6ed424f89e0bb7f0611b89a2ee947b6e0b1c089b Mon Sep 17 00:00:00 2001 From: 疯狂的狮子li <15040126243@163.com> Date: 星期四, 30 三月 2023 10:19:17 +0800 Subject: [PATCH] add 增加 邮箱验证码发送接口 add 增加 邮箱登陆接口 --- ruoyi-admin/src/main/java/com/ruoyi/web/controller/AuthController.java | 18 +++++ ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/LoginType.java | 5 + ruoyi-admin/src/main/resources/i18n/messages_en_US.properties | 4 + ruoyi-admin/src/main/java/com/ruoyi/web/service/SysLoginService.java | 47 +++++++++++++++ ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml | 10 +++ ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/model/SmsLoginBody.java | 4 ruoyi-admin/src/main/resources/i18n/messages.properties | 4 + ruoyi-admin/src/main/java/com/ruoyi/web/controller/CaptchaController.java | 28 ++++++++ ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java | 18 ++++++ ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/model/EmailLoginBody.java | 35 +++++++++++ ruoyi-admin/src/main/resources/i18n/messages_zh_CN.properties | 4 + 11 files changed, 172 insertions(+), 5 deletions(-) diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/AuthController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/AuthController.java index 81af4df..9c0a638 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/AuthController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/AuthController.java @@ -3,6 +3,7 @@ import cn.dev33.satoken.annotation.SaIgnore; import cn.hutool.core.collection.CollUtil; import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.core.domain.model.EmailLoginBody; import com.ruoyi.common.core.domain.model.LoginBody; import com.ruoyi.common.core.domain.model.RegisterBody; import com.ruoyi.common.core.domain.model.SmsLoginBody; @@ -62,7 +63,7 @@ } /** - * 鐭俊鐧诲綍(绀轰緥) + * 鐭俊鐧诲綍 * * @param body 鐧诲綍淇℃伅 * @return 缁撴灉 @@ -77,6 +78,21 @@ } /** + * 閭欢鐧诲綍 + * + * @param body 鐧诲綍淇℃伅 + * @return 缁撴灉 + */ + @PostMapping("/emailLogin") + public R<LoginVo> emailLogin(@Validated @RequestBody EmailLoginBody body) { + LoginVo loginVo = new LoginVo(); + // 鐢熸垚浠ょ墝 + String token = loginService.emailLogin(body.getTenantId(), body.getEmail(), body.getEmailCode()); + loginVo.setToken(token); + return R.ok(loginVo); + } + + /** * 灏忕▼搴忕櫥褰�(绀轰緥) * * @param xcxCode 灏忕▼搴廲ode diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/CaptchaController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/CaptchaController.java index ab9c4d1..757caf5 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/CaptchaController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/CaptchaController.java @@ -11,6 +11,8 @@ import com.ruoyi.common.core.utils.SpringUtils; import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.reflect.ReflectUtils; +import com.ruoyi.common.mail.config.properties.MailProperties; +import com.ruoyi.common.mail.utils.MailUtils; import com.ruoyi.common.redis.utils.RedisUtils; import com.ruoyi.common.sms.config.properties.SmsProperties; import com.ruoyi.common.sms.core.SmsTemplate; @@ -46,6 +48,7 @@ private final CaptchaProperties captchaProperties; private final SmsProperties smsProperties; + private final MailProperties mailProperties; /** * 鐭俊楠岃瘉鐮� @@ -53,8 +56,7 @@ * @param phonenumber 鐢ㄦ埛鎵嬫満鍙� */ @GetMapping("/sms/code") - public R<Void> smsCaptcha(@NotBlank(message = "{user.phonenumber.not.blank}") - String phonenumber) { + public R<Void> smsCode(@NotBlank(message = "{user.phonenumber.not.blank}") String phonenumber) { if (!smsProperties.getEnabled()) { return R.fail("褰撳墠绯荤粺娌℃湁寮�鍚煭淇″姛鑳斤紒"); } @@ -75,6 +77,28 @@ } /** + * 閭楠岃瘉鐮� + * + * @param email 閭 + */ + @GetMapping("/email/code") + public R<Void> emailCode(@NotBlank(message = "{user.email.not.blank}") String email) { + if (!mailProperties.getEnabled()) { + return R.fail("褰撳墠绯荤粺娌℃湁寮�鍚偖绠卞姛鑳斤紒"); + } + String key = GlobalConstants.CAPTCHA_CODE_KEY + email; + String code = RandomUtil.randomNumbers(4); + RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION)); + try { + MailUtils.sendText(email, "鐧诲綍楠岃瘉鐮�", "鎮ㄦ湰娆¢獙璇佺爜涓猴細" + code + "锛屾湁鏁堟�т负" + Constants.CAPTCHA_EXPIRATION + "鍒嗛挓锛岃灏藉揩濉啓銆�"); + } catch (Exception e) { + log.error("楠岃瘉鐮佺煭淇″彂閫佸紓甯� => {}", e.getMessage()); + return R.fail(e.getMessage()); + } + return R.ok(); + } + + /** * 鐢熸垚楠岃瘉鐮� */ @GetMapping("/code") diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/service/SysLoginService.java b/ruoyi-admin/src/main/java/com/ruoyi/web/service/SysLoginService.java index fece942..b853ab4 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/service/SysLoginService.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/service/SysLoginService.java @@ -112,6 +112,23 @@ return StpUtil.getTokenValue(); } + public String emailLogin(String tenantId, String email, String emailCode) { + // 鏍¢獙绉熸埛 + checkTenant(tenantId); + // 閫氳繃鎵嬫満鍙锋煡鎵剧敤鎴� + SysUserVo user = loadUserByEmail(tenantId, email); + + checkLogin(LoginType.EMAIL, tenantId, user.getUserName(), () -> !validateEmailCode(tenantId, email, emailCode)); + // 姝ゅ鍙牴鎹櫥褰曠敤鎴风殑鏁版嵁涓嶅悓 鑷鍒涘缓 loginUser + LoginUser loginUser = buildLoginUser(user); + // 鐢熸垚token + LoginHelper.loginByDevice(loginUser, DeviceType.APP); + + recordLogininfor(loginUser.getTenantId(), user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")); + recordLoginInfo(user.getUserId()); + return StpUtil.getTokenValue(); + } + public String xcxLogin(String xcxCode) { // xcxCode 涓� 灏忕▼搴忚皟鐢� wx.login 鎺堟潈鍚庤幏鍙� @@ -185,6 +202,18 @@ } /** + * 鏍¢獙閭楠岃瘉鐮� + */ + private boolean validateEmailCode(String tenantId, String email, String emailCode) { + String code = RedisUtils.getCacheObject(GlobalConstants.CAPTCHA_CODE_KEY + email); + if (StringUtils.isBlank(code)) { + recordLogininfor(tenantId, email, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")); + throw new CaptchaExpireException(); + } + return code.equals(emailCode); + } + + /** * 鏍¢獙楠岃瘉鐮� * * @param username 鐢ㄦ埛鍚� @@ -241,6 +270,24 @@ return userMapper.selectUserByPhonenumber(phonenumber); } + private SysUserVo loadUserByEmail(String tenantId, String email) { + SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>() + .select(SysUser::getPhonenumber, SysUser::getStatus) + .eq(TenantHelper.isEnable(), SysUser::getTenantId, tenantId) + .eq(SysUser::getEmail, email)); + if (ObjectUtil.isNull(user)) { + log.info("鐧诲綍鐢ㄦ埛锛歿} 涓嶅瓨鍦�.", email); + throw new UserException("user.not.exists", email); + } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) { + log.info("鐧诲綍鐢ㄦ埛锛歿} 宸茶鍋滅敤.", email); + throw new UserException("user.blocked", email); + } + if (TenantHelper.isEnable()) { + return userMapper.selectTenantUserByEmail(email, tenantId); + } + return userMapper.selectUserByEmail(email); + } + private SysUserVo loadUserByOpenid(String openid) { // 浣跨敤 openid 鏌ヨ缁戝畾鐢ㄦ埛 濡傛湭缁戝畾鐢ㄦ埛 鍒欐牴鎹笟鍔¤嚜琛屽鐞� 渚嬪 鍒涘缓榛樿鐢ㄦ埛 // todo 鑷瀹炵幇 userService.selectUserByOpenid(openid); diff --git a/ruoyi-admin/src/main/resources/i18n/messages.properties b/ruoyi-admin/src/main/resources/i18n/messages.properties index 3a5eeac..4f2da28 100644 --- a/ruoyi-admin/src/main/resources/i18n/messages.properties +++ b/ruoyi-admin/src/main/resources/i18n/messages.properties @@ -18,6 +18,7 @@ user.password.length.valid=鐢ㄦ埛瀵嗙爜闀垮害蹇呴』鍦▄min}鍒皗max}涓瓧绗︿箣闂� user.password.not.valid=* 5-50涓瓧绗� user.email.not.valid=閭鏍煎紡閿欒 +user.email.not.blank=閭涓嶈兘涓虹┖ user.phonenumber.not.blank=鐢ㄦ埛鎵嬫満鍙蜂笉鑳戒负绌� user.mobile.phone.number.not.valid=鎵嬫満鍙锋牸寮忛敊璇� user.login.success=鐧诲綍鎴愬姛 @@ -42,6 +43,9 @@ sms.code.not.blank=鐭俊楠岃瘉鐮佷笉鑳戒负绌� sms.code.retry.limit.count=鐭俊楠岃瘉鐮佽緭鍏ラ敊璇瘂0}娆� sms.code.retry.limit.exceed=鐭俊楠岃瘉鐮佽緭鍏ラ敊璇瘂0}娆★紝甯愭埛閿佸畾{1}鍒嗛挓 +email.code.not.blank=閭楠岃瘉鐮佷笉鑳戒负绌� +email.code.retry.limit.count=閭楠岃瘉鐮佽緭鍏ラ敊璇瘂0}娆� +email.code.retry.limit.exceed=閭楠岃瘉鐮佽緭鍏ラ敊璇瘂0}娆★紝甯愭埛閿佸畾{1}鍒嗛挓 xcx.code.not.blank=灏忕▼搴廲ode涓嶈兘涓虹┖ ##绉熸埛 tenant.number.not.blank=绉熸埛缂栧彿涓嶈兘涓虹┖ diff --git a/ruoyi-admin/src/main/resources/i18n/messages_en_US.properties b/ruoyi-admin/src/main/resources/i18n/messages_en_US.properties index 7568f68..0c738a3 100644 --- a/ruoyi-admin/src/main/resources/i18n/messages_en_US.properties +++ b/ruoyi-admin/src/main/resources/i18n/messages_en_US.properties @@ -18,6 +18,7 @@ user.password.length.valid=Password length must be between {min} and {max} characters user.password.not.valid=* 5-50 characters user.email.not.valid=Mailbox format error +user.email.not.blank=Mailbox cannot be blank user.phonenumber.not.blank=Phone number cannot be blank user.mobile.phone.number.not.valid=Phone number format error user.login.success=Login successful @@ -42,6 +43,9 @@ sms.code.not.blank=Sms code cannot be blank sms.code.retry.limit.count=Sms code input error {0} times sms.code.retry.limit.exceed=Sms code input error {0} times, account locked for {1} minutes +email.code.not.blank=Email code cannot be blank +email.code.retry.limit.count=Email code input error {0} times +email.code.retry.limit.exceed=Email code input error {0} times, account locked for {1} minutes xcx.code.not.blank=Mini program code cannot be blank ##绉熸埛 tenant.number.not.blank=Tenant number cannot be blank diff --git a/ruoyi-admin/src/main/resources/i18n/messages_zh_CN.properties b/ruoyi-admin/src/main/resources/i18n/messages_zh_CN.properties index 3a5eeac..4f2da28 100644 --- a/ruoyi-admin/src/main/resources/i18n/messages_zh_CN.properties +++ b/ruoyi-admin/src/main/resources/i18n/messages_zh_CN.properties @@ -18,6 +18,7 @@ user.password.length.valid=鐢ㄦ埛瀵嗙爜闀垮害蹇呴』鍦▄min}鍒皗max}涓瓧绗︿箣闂� user.password.not.valid=* 5-50涓瓧绗� user.email.not.valid=閭鏍煎紡閿欒 +user.email.not.blank=閭涓嶈兘涓虹┖ user.phonenumber.not.blank=鐢ㄦ埛鎵嬫満鍙蜂笉鑳戒负绌� user.mobile.phone.number.not.valid=鎵嬫満鍙锋牸寮忛敊璇� user.login.success=鐧诲綍鎴愬姛 @@ -42,6 +43,9 @@ sms.code.not.blank=鐭俊楠岃瘉鐮佷笉鑳戒负绌� sms.code.retry.limit.count=鐭俊楠岃瘉鐮佽緭鍏ラ敊璇瘂0}娆� sms.code.retry.limit.exceed=鐭俊楠岃瘉鐮佽緭鍏ラ敊璇瘂0}娆★紝甯愭埛閿佸畾{1}鍒嗛挓 +email.code.not.blank=閭楠岃瘉鐮佷笉鑳戒负绌� +email.code.retry.limit.count=閭楠岃瘉鐮佽緭鍏ラ敊璇瘂0}娆� +email.code.retry.limit.exceed=閭楠岃瘉鐮佽緭鍏ラ敊璇瘂0}娆★紝甯愭埛閿佸畾{1}鍒嗛挓 xcx.code.not.blank=灏忕▼搴廲ode涓嶈兘涓虹┖ ##绉熸埛 tenant.number.not.blank=绉熸埛缂栧彿涓嶈兘涓虹┖ diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/model/EmailLoginBody.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/model/EmailLoginBody.java new file mode 100644 index 0000000..6459673 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/model/EmailLoginBody.java @@ -0,0 +1,35 @@ +package com.ruoyi.common.core.domain.model; + +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; + +/** + * 鐭俊鐧诲綍瀵硅薄 + * + * @author Lion Li + */ + +@Data +public class EmailLoginBody { + + /** + * 绉熸埛ID + */ + @NotBlank(message = "{tenant.number.not.blank}") + private String tenantId; + + /** + * 閭 + */ + @NotBlank(message = "{user.email.not.blank}") + @Email(message = "{user.email.not.valid}") + private String email; + + /** + * 閭code + */ + @NotBlank(message = "{email.code.not.blank}") + private String emailCode; + +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/model/SmsLoginBody.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/model/SmsLoginBody.java index 3b25fce..70df20d 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/model/SmsLoginBody.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/domain/model/SmsLoginBody.java @@ -20,13 +20,13 @@ private String tenantId; /** - * 鐢ㄦ埛鍚� + * 鎵嬫満鍙� */ @NotBlank(message = "{user.phonenumber.not.blank}") private String phonenumber; /** - * 鐢ㄦ埛瀵嗙爜 + * 鐭俊code */ @NotBlank(message = "{sms.code.not.blank}") private String smsCode; diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/LoginType.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/LoginType.java index fcd48df..dbd6de1 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/LoginType.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/LoginType.java @@ -23,6 +23,11 @@ SMS("sms.code.retry.limit.exceed", "sms.code.retry.limit.count"), /** + * 閭鐧诲綍 + */ + EMAIL("email.code.retry.limit.exceed", "email.code.retry.limit.count"), + + /** * 灏忕▼搴忕櫥褰� */ XCX("", ""); diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java index 84b26fd..2aacf48 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java @@ -79,6 +79,14 @@ SysUserVo selectUserByPhonenumber(String phonenumber); /** + * 閫氳繃閭鏌ヨ鐢ㄦ埛 + * + * @param email 閭 + * @return 鐢ㄦ埛瀵硅薄淇℃伅 + */ + SysUserVo selectUserByEmail(String email); + + /** * 閫氳繃鐢ㄦ埛鍚嶆煡璇㈢敤鎴�(涓嶈蛋绉熸埛鎻掍欢) * * @param userName 鐢ㄦ埛鍚� @@ -99,6 +107,16 @@ SysUserVo selectTenantUserByPhonenumber(String phonenumber, String tenantId); /** + * 閫氳繃閭鏌ヨ鐢ㄦ埛(涓嶈蛋绉熸埛鎻掍欢) + * + * @param email 閭 + * @param tenantId 绉熸埛id + * @return 鐢ㄦ埛瀵硅薄淇℃伅 + */ + @InterceptorIgnore(tenantLine = "true") + SysUserVo selectTenantUserByEmail(String email, String tenantId); + + /** * 閫氳繃鐢ㄦ埛ID鏌ヨ鐢ㄦ埛 * * @param userId 鐢ㄦ埛ID diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml index 481c17a..92d8c9e 100644 --- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml @@ -102,6 +102,11 @@ where u.del_flag = '0' and u.phonenumber = #{phonenumber} </select> + <select id="selectUserByEmail" parameterType="String" resultMap="SysUserResult"> + <include refid="selectUserVo"/> + where u.del_flag = '0' and u.email = #{email} + </select> + <select id="selectTenantUserByUserName" parameterType="String" resultMap="SysUserResult"> <include refid="selectUserVo"/> where u.del_flag = '0' and u.user_name = #{userName} and u.tenant_id = #{tenantId} @@ -112,6 +117,11 @@ where u.del_flag = '0' and u.phonenumber = #{phonenumber} and u.tenant_id = #{tenantId} </select> + <select id="selectTenantUserByEmail" parameterType="String" resultMap="SysUserResult"> + <include refid="selectUserVo"/> + where u.del_flag = '0' and u.email = #{email} and u.tenant_id = #{tenantId} + </select> + <select id="selectUserById" parameterType="Long" resultMap="SysUserResult"> <include refid="selectUserVo"/> where u.del_flag = '0' and u.user_id = #{userId} -- Gitblit v1.9.3