feat: 支持邮箱登录
在个人中心-安全设置中绑定邮箱后,才支持邮箱登录
This commit is contained in:
parent
d9af44f9fa
commit
17b169eb0e
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user