mirror of
				https://github.com/continew-org/continew-admin.git
				synced 2025-10-31 22:57:17 +08:00 
			
		
		
		
	feat: 支持邮箱登录
在个人中心-安全设置中绑定邮箱后,才支持邮箱登录
This commit is contained in:
		| @@ -0,0 +1,59 @@ | |||||||
|  | /* | ||||||
|  |  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||||
|  |  * | ||||||
|  |  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |  * you may not use this file except in compliance with the License. | ||||||
|  |  * You may obtain a copy of the License at | ||||||
|  |  * | ||||||
|  |  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  * Unless required by applicable law or agreed to in writing, software | ||||||
|  |  * distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  * See the License for the specific language governing permissions and | ||||||
|  |  * limitations under the License. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | package top.charles7c.cnadmin.auth.model.request; | ||||||
|  |  | ||||||
|  | import java.io.Serializable; | ||||||
|  |  | ||||||
|  | import javax.validation.constraints.NotBlank; | ||||||
|  | import javax.validation.constraints.Pattern; | ||||||
|  |  | ||||||
|  | import lombok.Data; | ||||||
|  |  | ||||||
|  | import io.swagger.v3.oas.annotations.media.Schema; | ||||||
|  |  | ||||||
|  | import org.hibernate.validator.constraints.Length; | ||||||
|  |  | ||||||
|  | import top.charles7c.cnadmin.common.constant.RegexConsts; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 邮箱登录信息 | ||||||
|  |  * | ||||||
|  |  * @author Charles7c | ||||||
|  |  * @since 2023/10/23 20:15 | ||||||
|  |  */ | ||||||
|  | @Data | ||||||
|  | @Schema(description = "邮箱登录信息") | ||||||
|  | public class EmailLoginRequest implements Serializable { | ||||||
|  |  | ||||||
|  |     private static final long serialVersionUID = 1L; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 邮箱 | ||||||
|  |      */ | ||||||
|  |     @Schema(description = "邮箱", example = "123456789@qq.com") | ||||||
|  |     @NotBlank(message = "邮箱不能为空") | ||||||
|  |     @Pattern(regexp = RegexConsts.EMAIL, message = "邮箱格式错误") | ||||||
|  |     private String email; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 验证码 | ||||||
|  |      */ | ||||||
|  |     @Schema(description = "验证码", example = "888888") | ||||||
|  |     @NotBlank(message = "验证码不能为空") | ||||||
|  |     @Length(max = 6, message = "验证码非法") | ||||||
|  |     private String captcha; | ||||||
|  | } | ||||||
| @@ -31,7 +31,7 @@ import me.zhyd.oauth.model.AuthUser; | |||||||
| public interface LoginService { | public interface LoginService { | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 用户登录 |      * 账号登录 | ||||||
|      * |      * | ||||||
|      * @param username |      * @param username | ||||||
|      *            用户名 |      *            用户名 | ||||||
| @@ -39,7 +39,16 @@ public interface LoginService { | |||||||
|      *            密码 |      *            密码 | ||||||
|      * @return 令牌 |      * @return 令牌 | ||||||
|      */ |      */ | ||||||
|     String login(String username, String password); |     String accountLogin(String username, String password); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 邮箱登录 | ||||||
|  |      * | ||||||
|  |      * @param email | ||||||
|  |      *            邮箱 | ||||||
|  |      * @return 令牌 | ||||||
|  |      */ | ||||||
|  |     String emailLogin(String email); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 三方账号登录 |      * 三方账号登录 | ||||||
|   | |||||||
| @@ -76,11 +76,19 @@ public class LoginServiceImpl implements LoginService { | |||||||
|     private final UserSocialService userSocialService; |     private final UserSocialService userSocialService; | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public String login(String username, String password) { |     public String accountLogin(String username, String password) { | ||||||
|         UserDO user = userService.getByUsername(username); |         UserDO user = userService.getByUsername(username); | ||||||
|         CheckUtils.throwIfNull(user, "用户名或密码错误"); |         CheckUtils.throwIfNull(user, "用户名或密码不正确"); | ||||||
|         Long userId = user.getId(); |         Long userId = user.getId(); | ||||||
|         CheckUtils.throwIfNotEqual(SecureUtils.md5Salt(password, userId.toString()), user.getPassword(), "用户名或密码错误"); |         CheckUtils.throwIfNotEqual(SecureUtils.md5Salt(password, userId.toString()), user.getPassword(), "用户名或密码不正确"); | ||||||
|  |         this.checkUserStatus(user); | ||||||
|  |         return this.login(user); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public String emailLogin(String email) { | ||||||
|  |         UserDO user = userService.getByEmail(email); | ||||||
|  |         CheckUtils.throwIfNull(user, "此邮箱未绑定本系统账号"); | ||||||
|         this.checkUserStatus(user); |         this.checkUserStatus(user); | ||||||
|         return this.login(user); |         return this.login(user); | ||||||
|     } |     } | ||||||
| @@ -187,6 +195,6 @@ public class LoginServiceImpl implements LoginService { | |||||||
|     private void checkUserStatus(UserDO user) { |     private void checkUserStatus(UserDO user) { | ||||||
|         CheckUtils.throwIfEqual(DisEnableStatusEnum.DISABLE, user.getStatus(), "此账号已被禁用,如有疑问,请联系管理员"); |         CheckUtils.throwIfEqual(DisEnableStatusEnum.DISABLE, user.getStatus(), "此账号已被禁用,如有疑问,请联系管理员"); | ||||||
|         DeptDetailVO deptDetailVO = deptService.get(user.getDeptId()); |         DeptDetailVO deptDetailVO = deptService.get(user.getDeptId()); | ||||||
|         CheckUtils.throwIfEqual(DisEnableStatusEnum.DISABLE, deptDetailVO.getStatus(), "此账号部门已被禁用,如有疑问,请联系管理员"); |         CheckUtils.throwIfEqual(DisEnableStatusEnum.DISABLE, deptDetailVO.getStatus(), "此账号所属部门已被禁用,如有疑问,请联系管理员"); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -40,6 +40,16 @@ public interface UserMapper extends DataPermissionMapper<UserDO> { | |||||||
|     @Select("SELECT * FROM `sys_user` WHERE `username` = #{username}") |     @Select("SELECT * FROM `sys_user` WHERE `username` = #{username}") | ||||||
|     UserDO selectByUsername(@Param("username") String username); |     UserDO selectByUsername(@Param("username") String username); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 根据邮箱查询 | ||||||
|  |      * | ||||||
|  |      * @param email | ||||||
|  |      *            邮箱 | ||||||
|  |      * @return 用户信息 | ||||||
|  |      */ | ||||||
|  |     @Select("SELECT * FROM `sys_user` WHERE `email` = #{email}") | ||||||
|  |     UserDO selectByEmail(@Param("email") String email); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 根据 ID 查询昵称 |      * 根据 ID 查询昵称 | ||||||
|      * |      * | ||||||
|   | |||||||
| @@ -118,6 +118,15 @@ public interface UserService extends BaseService<UserVO, UserDetailVO, UserQuery | |||||||
|      */ |      */ | ||||||
|     UserDO getByUsername(String username); |     UserDO getByUsername(String username); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 根据邮箱查询 | ||||||
|  |      * | ||||||
|  |      * @param email | ||||||
|  |      *            邮箱 | ||||||
|  |      * @return 用户信息 | ||||||
|  |      */ | ||||||
|  |     UserDO getByEmail(String email); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 根据部门 ID 列表查询 |      * 根据部门 ID 列表查询 | ||||||
|      * |      * | ||||||
|   | |||||||
| @@ -244,6 +244,11 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserVO, | |||||||
|         return baseMapper.selectByUsername(username); |         return baseMapper.selectByUsername(username); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public UserDO getByEmail(String email) { | ||||||
|  |         return baseMapper.selectByEmail(email); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public Long countByDeptIds(List<Long> deptIds) { |     public Long countByDeptIds(List<Long> deptIds) { | ||||||
|         return baseMapper.lambdaQuery().in(UserDO::getDeptId, deptIds).count(); |         return baseMapper.lambdaQuery().in(UserDO::getDeptId, deptIds).count(); | ||||||
|   | |||||||
| @@ -6,7 +6,6 @@ const BASE_URL = '/auth'; | |||||||
|  |  | ||||||
| export interface LoginReq { | export interface LoginReq { | ||||||
|   phone?: string; |   phone?: string; | ||||||
|   email?: string; |  | ||||||
|   username?: string; |   username?: string; | ||||||
|   password?: string; |   password?: string; | ||||||
|   captcha: string; |   captcha: string; | ||||||
| @@ -17,8 +16,17 @@ export interface LoginRes { | |||||||
|   token: string; |   token: string; | ||||||
| } | } | ||||||
|  |  | ||||||
| export function login(req: LoginReq) { | export function accountLogin(req: LoginReq) { | ||||||
|   return axios.post<LoginRes>(`${BASE_URL}/login`, req); |   return axios.post<LoginRes>(`${BASE_URL}/account`, req); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export interface EmailLoginReq { | ||||||
|  |   email: string; | ||||||
|  |   captcha: string; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export function emailLogin(req: EmailLoginReq) { | ||||||
|  |   return axios.post<LoginRes>(`${BASE_URL}/email`, req); | ||||||
| } | } | ||||||
|  |  | ||||||
| export function logout() { | export function logout() { | ||||||
| @@ -34,9 +42,9 @@ export function listRoute() { | |||||||
| } | } | ||||||
|  |  | ||||||
| export function socialAuth(source: string) { | export function socialAuth(source: string) { | ||||||
|   return axios.get<string>(`${BASE_URL}/${source}`); |   return axios.get<string>(`/oauth/${source}`); | ||||||
| } | } | ||||||
|  |  | ||||||
| export function socialLogin(source: string, req: any) { | export function socialLogin(source: string, req: any) { | ||||||
|   return axios.post<LoginRes>(`${BASE_URL}/${source}`, req); |   return axios.post<LoginRes>(`/oauth/${source}`, req); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,10 +1,12 @@ | |||||||
| import { defineStore } from 'pinia'; | import { defineStore } from 'pinia'; | ||||||
| import { | import { | ||||||
|   login as userLogin, |   LoginReq, | ||||||
|  |   EmailLoginReq, | ||||||
|  |   accountLogin as userAccountLogin, | ||||||
|  |   emailLogin as userEmailLogin, | ||||||
|   socialLogin as userSocialLogin, |   socialLogin as userSocialLogin, | ||||||
|   logout as userLogout, |   logout as userLogout, | ||||||
|   getUserInfo, |   getUserInfo, | ||||||
|   LoginReq, |  | ||||||
| } from '@/api/auth/login'; | } from '@/api/auth/login'; | ||||||
| import { getImageCaptcha as getCaptcha } from '@/api/common/captcha'; | import { getImageCaptcha as getCaptcha } from '@/api/common/captcha'; | ||||||
| import { setToken, clearToken } from '@/utils/auth'; | import { setToken, clearToken } from '@/utils/auth'; | ||||||
| @@ -42,10 +44,21 @@ const useUserStore = defineStore('user', { | |||||||
|       return getCaptcha(); |       return getCaptcha(); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     // 用户登录 |     // 账号登录 | ||||||
|     async login(req: LoginReq) { |     async accountLogin(req: LoginReq) { | ||||||
|       try { |       try { | ||||||
|         const res = await userLogin(req); |         const res = await userAccountLogin(req); | ||||||
|  |         setToken(res.data.token); | ||||||
|  |       } catch (err) { | ||||||
|  |         clearToken(); | ||||||
|  |         throw err; | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     // 邮箱登录 | ||||||
|  |     async emailLogin(req: EmailLoginReq) { | ||||||
|  |       try { | ||||||
|  |         const res = await userEmailLogin(req); | ||||||
|         setToken(res.data.token); |         setToken(res.data.token); | ||||||
|       } catch (err) { |       } catch (err) { | ||||||
|         clearToken(); |         clearToken(); | ||||||
|   | |||||||
| @@ -124,7 +124,7 @@ | |||||||
|     if (!errors) { |     if (!errors) { | ||||||
|       loading.value = true; |       loading.value = true; | ||||||
|       userStore |       userStore | ||||||
|         .login({ |         .accountLogin({ | ||||||
|           username: values.username, |           username: values.username, | ||||||
|           password: encryptByRsa(values.password) || '', |           password: encryptByRsa(values.password) || '', | ||||||
|           captcha: values.captcha, |           captcha: values.captcha, | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ | |||||||
|     layout="vertical" |     layout="vertical" | ||||||
|     size="large" |     size="large" | ||||||
|     class="login-form" |     class="login-form" | ||||||
|  |     @submit="handleLogin" | ||||||
|   > |   > | ||||||
|     <a-form-item field="email" hide-label> |     <a-form-item field="email" hide-label> | ||||||
|       <a-input |       <a-input | ||||||
| @@ -32,7 +33,7 @@ | |||||||
|       </a-button> |       </a-button> | ||||||
|     </a-form-item> |     </a-form-item> | ||||||
|     <a-button class="btn" :loading="loading" type="primary" html-type="submit" |     <a-button class="btn" :loading="loading" type="primary" html-type="submit" | ||||||
|       >{{ $t('login.button') }}(即将开放) |       >{{ $t('login.button') }} | ||||||
|     </a-button> |     </a-button> | ||||||
|   </a-form> |   </a-form> | ||||||
| </template> | </template> | ||||||
| @@ -40,11 +41,15 @@ | |||||||
| <script lang="ts" setup> | <script lang="ts" setup> | ||||||
|   import { getCurrentInstance, ref, toRefs, reactive, computed } from 'vue'; |   import { getCurrentInstance, ref, toRefs, reactive, computed } from 'vue'; | ||||||
|   import { useI18n } from 'vue-i18n'; |   import { useI18n } from 'vue-i18n'; | ||||||
|  |   import { useRouter } from 'vue-router'; | ||||||
|  |   import { ValidatedError } from '@arco-design/web-vue'; | ||||||
|   import { useUserStore } from '@/store'; |   import { useUserStore } from '@/store'; | ||||||
|   import { LoginReq } from '@/api/auth/login'; |   import { EmailLoginReq } from '@/api/auth/login'; | ||||||
|  |   import { getMailCaptcha } from '@/api/common/captcha'; | ||||||
|  |  | ||||||
|   const { proxy } = getCurrentInstance() as any; |   const { proxy } = getCurrentInstance() as any; | ||||||
|   const { t } = useI18n(); |   const { t } = useI18n(); | ||||||
|  |   const router = useRouter(); | ||||||
|   const userStore = useUserStore(); |   const userStore = useUserStore(); | ||||||
|   const loading = ref(false); |   const loading = ref(false); | ||||||
|   const captchaLoading = ref(false); |   const captchaLoading = ref(false); | ||||||
| @@ -54,7 +59,10 @@ | |||||||
|   const captchaBtnNameKey = ref('login.captcha.get'); |   const captchaBtnNameKey = ref('login.captcha.get'); | ||||||
|   const captchaBtnName = computed(() => t(captchaBtnNameKey.value)); |   const captchaBtnName = computed(() => t(captchaBtnNameKey.value)); | ||||||
|   const data = reactive({ |   const data = reactive({ | ||||||
|     form: {} as LoginReq, |     form: { | ||||||
|  |       email: '', | ||||||
|  |       captcha: '', | ||||||
|  |     } as EmailLoginReq, | ||||||
|     rules: { |     rules: { | ||||||
|       email: [ |       email: [ | ||||||
|         { required: true, message: t('login.email.error.required.email') }, |         { required: true, message: t('login.email.error.required.email') }, | ||||||
| @@ -85,26 +93,76 @@ | |||||||
|       if (!valid) { |       if (!valid) { | ||||||
|         captchaLoading.value = true; |         captchaLoading.value = true; | ||||||
|         captchaBtnNameKey.value = 'login.captcha.ing'; |         captchaBtnNameKey.value = 'login.captcha.ing'; | ||||||
|         captchaLoading.value = false; |         getMailCaptcha({ | ||||||
|         captchaDisable.value = true; |           email: form.value.email, | ||||||
|         captchaBtnNameKey.value = `${t( |         }) | ||||||
|           'login.captcha.get' |           .then((res) => { | ||||||
|         )}(${(captchaTime.value -= 1)}s)`; |             captchaLoading.value = false; | ||||||
|         captchaTimer.value = window.setInterval(() => { |             captchaDisable.value = true; | ||||||
|           captchaTime.value -= 1; |             captchaBtnNameKey.value = `${t( | ||||||
|           captchaBtnNameKey.value = `${t('login.captcha.get')}(${ |               'login.captcha.get' | ||||||
|             captchaTime.value |             )}(${(captchaTime.value -= 1)}s)`; | ||||||
|           }s)`; |             captchaTimer.value = window.setInterval(() => { | ||||||
|           if (captchaTime.value < 0) { |               captchaTime.value -= 1; | ||||||
|             window.clearInterval(captchaTimer.value); |               captchaBtnNameKey.value = `${t('login.captcha.get')}(${ | ||||||
|             captchaTime.value = 60; |                 captchaTime.value | ||||||
|             captchaBtnNameKey.value = t('login.captcha.get'); |               }s)`; | ||||||
|             captchaDisable.value = false; |               if (captchaTime.value <= 0) { | ||||||
|           } |                 window.clearInterval(captchaTimer.value); | ||||||
|         }, 1000); |                 captchaTime.value = 60; | ||||||
|  |                 captchaBtnNameKey.value = t('login.captcha.get'); | ||||||
|  |                 captchaDisable.value = false; | ||||||
|  |               } | ||||||
|  |             }, 1000); | ||||||
|  |             proxy.$message.success(res.msg); | ||||||
|  |           }) | ||||||
|  |           .catch(() => { | ||||||
|  |             resetCaptcha(); | ||||||
|  |             captchaLoading.value = false; | ||||||
|  |           }); | ||||||
|       } |       } | ||||||
|     }); |     }); | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 登录 | ||||||
|  |    * | ||||||
|  |    * @param errors 表单验证错误 | ||||||
|  |    * @param values 表单数据 | ||||||
|  |    */ | ||||||
|  |   const handleLogin = ({ | ||||||
|  |     errors, | ||||||
|  |     values, | ||||||
|  |   }: { | ||||||
|  |     errors: Record<string, ValidatedError> | undefined; | ||||||
|  |     values: Record<string, any>; | ||||||
|  |   }) => { | ||||||
|  |     if (loading.value) return; | ||||||
|  |     if (!errors) { | ||||||
|  |       loading.value = true; | ||||||
|  |       userStore | ||||||
|  |         .emailLogin({ | ||||||
|  |           email: values.email, | ||||||
|  |           captcha: values.captcha, | ||||||
|  |         }) | ||||||
|  |         .then(() => { | ||||||
|  |           const { redirect, ...othersQuery } = router.currentRoute.value.query; | ||||||
|  |           router.push({ | ||||||
|  |             name: (redirect as string) || 'Workplace', | ||||||
|  |             query: { | ||||||
|  |               ...othersQuery, | ||||||
|  |             }, | ||||||
|  |           }); | ||||||
|  |           proxy.$notification.success(t('login.success')); | ||||||
|  |         }) | ||||||
|  |         .catch(() => { | ||||||
|  |           form.value.captcha = ''; | ||||||
|  |         }) | ||||||
|  |         .finally(() => { | ||||||
|  |           loading.value = false; | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |   }; | ||||||
| </script> | </script> | ||||||
|  |  | ||||||
| <style lang="less" scoped> | <style lang="less" scoped> | ||||||
|   | |||||||
| @@ -77,7 +77,7 @@ export default { | |||||||
|   // update-email |   // update-email | ||||||
|   'userCenter.securitySettings.email.label': 'Email', |   'userCenter.securitySettings.email.label': 'Email', | ||||||
|   'userCenter.securitySettings.email.tip': |   'userCenter.securitySettings.email.tip': | ||||||
|     'Used to receive messages, verify identity', |     'It is used to receive messages, verify identity, and support email login after binding', | ||||||
|   'userCenter.securitySettings.email.content': 'Unbound', |   'userCenter.securitySettings.email.content': 'Unbound', | ||||||
|  |  | ||||||
|   'userCenter.securitySettings.updateEmail.modal.title': 'Update email', |   'userCenter.securitySettings.updateEmail.modal.title': 'Update email', | ||||||
|   | |||||||
| @@ -72,7 +72,8 @@ export default { | |||||||
|  |  | ||||||
|   // update-email |   // update-email | ||||||
|   'userCenter.securitySettings.email.label': '安全邮箱', |   'userCenter.securitySettings.email.label': '安全邮箱', | ||||||
|   'userCenter.securitySettings.email.tip': '用于接收消息、验证身份', |   'userCenter.securitySettings.email.tip': | ||||||
|  |     '用于接收消息、验证身份,绑定后可支持邮箱登录', | ||||||
|   'userCenter.securitySettings.email.content': '未绑定', |   'userCenter.securitySettings.email.content': '未绑定', | ||||||
|  |  | ||||||
|   'userCenter.securitySettings.updateEmail.modal.title': '修改邮箱', |   'userCenter.securitySettings.updateEmail.modal.title': '修改邮箱', | ||||||
|   | |||||||
| @@ -32,6 +32,7 @@ import cn.dev33.satoken.annotation.SaIgnore; | |||||||
| import cn.dev33.satoken.stp.StpUtil; | import cn.dev33.satoken.stp.StpUtil; | ||||||
| import cn.hutool.core.bean.BeanUtil; | import cn.hutool.core.bean.BeanUtil; | ||||||
|  |  | ||||||
|  | import top.charles7c.cnadmin.auth.model.request.EmailLoginRequest; | ||||||
| import top.charles7c.cnadmin.auth.model.request.LoginRequest; | import top.charles7c.cnadmin.auth.model.request.LoginRequest; | ||||||
| import top.charles7c.cnadmin.auth.model.vo.LoginVO; | import top.charles7c.cnadmin.auth.model.vo.LoginVO; | ||||||
| import top.charles7c.cnadmin.auth.model.vo.RouteVO; | import top.charles7c.cnadmin.auth.model.vo.RouteVO; | ||||||
| @@ -65,9 +66,9 @@ public class AuthController { | |||||||
|     private final UserService userService; |     private final UserService userService; | ||||||
|  |  | ||||||
|     @SaIgnore |     @SaIgnore | ||||||
|     @Operation(summary = "用户登录", description = "根据用户名和密码进行登录认证") |     @Operation(summary = "账号登录", description = "根据账号和密码进行登录认证") | ||||||
|     @PostMapping("/login") |     @PostMapping("/account") | ||||||
|     public LoginVO login(@Validated @RequestBody LoginRequest loginRequest) { |     public LoginVO accountLogin(@Validated @RequestBody LoginRequest loginRequest) { | ||||||
|         String captchaKey = RedisUtils.formatKey(CacheConsts.CAPTCHA_KEY_PREFIX, loginRequest.getUuid()); |         String captchaKey = RedisUtils.formatKey(CacheConsts.CAPTCHA_KEY_PREFIX, loginRequest.getUuid()); | ||||||
|         String captcha = RedisUtils.getCacheObject(captchaKey); |         String captcha = RedisUtils.getCacheObject(captchaKey); | ||||||
|         ValidationUtils.throwIfBlank(captcha, "验证码已失效"); |         ValidationUtils.throwIfBlank(captcha, "验证码已失效"); | ||||||
| @@ -77,7 +78,21 @@ public class AuthController { | |||||||
|         String rawPassword = |         String rawPassword = | ||||||
|             ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(loginRequest.getPassword())); |             ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(loginRequest.getPassword())); | ||||||
|         ValidationUtils.throwIfBlank(rawPassword, "密码解密失败"); |         ValidationUtils.throwIfBlank(rawPassword, "密码解密失败"); | ||||||
|         String token = loginService.login(loginRequest.getUsername(), rawPassword); |         String token = loginService.accountLogin(loginRequest.getUsername(), rawPassword); | ||||||
|  |         return LoginVO.builder().token(token).build(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @SaIgnore | ||||||
|  |     @Operation(summary = "邮箱登录", description = "根据邮箱和验证码进行登录认证") | ||||||
|  |     @PostMapping("/email") | ||||||
|  |     public LoginVO emailLogin(@Validated @RequestBody EmailLoginRequest loginRequest) { | ||||||
|  |         String email = loginRequest.getEmail(); | ||||||
|  |         String captchaKey = RedisUtils.formatKey(CacheConsts.CAPTCHA_KEY_PREFIX, email); | ||||||
|  |         String captcha = RedisUtils.getCacheObject(captchaKey); | ||||||
|  |         ValidationUtils.throwIfBlank(captcha, "验证码已失效"); | ||||||
|  |         ValidationUtils.throwIfNotEqualIgnoreCase(loginRequest.getCaptcha(), captcha, "验证码错误"); | ||||||
|  |         RedisUtils.deleteCacheObject(captchaKey); | ||||||
|  |         String token = loginService.emailLogin(email); | ||||||
|         return LoginVO.builder().token(token).build(); |         return LoginVO.builder().token(token).build(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -54,7 +54,7 @@ import me.zhyd.oauth.utils.AuthStateUtils; | |||||||
| @SaIgnore | @SaIgnore | ||||||
| @RestController | @RestController | ||||||
| @RequiredArgsConstructor | @RequiredArgsConstructor | ||||||
| @RequestMapping("/auth") | @RequestMapping("/oauth") | ||||||
| public class SocialAuthController { | public class SocialAuthController { | ||||||
|  |  | ||||||
|     private final LoginService loginService; |     private final LoginService loginService; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user