mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-21 22:53:56 +08:00
update:web端重置密码页面加密
This commit is contained in:
+32
@@ -257,6 +257,38 @@ public class LoginController {
|
|||||||
throw new RenException(ErrorCode.SMS_CODE_ERROR);
|
throw new RenException(ErrorCode.SMS_CODE_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String password = dto.getPassword();
|
||||||
|
|
||||||
|
// 获取SM2私钥
|
||||||
|
String privateKeyStr = sysParamsService.getValue(Constant.SM2_PRIVATE_KEY, true);
|
||||||
|
if (StringUtils.isBlank(privateKeyStr)) {
|
||||||
|
throw new RenException(ErrorCode.SM2_KEY_NOT_CONFIGURED);
|
||||||
|
}
|
||||||
|
|
||||||
|
String decryptedContent;
|
||||||
|
try {
|
||||||
|
// 使用SM2私钥解密密码
|
||||||
|
decryptedContent = SM2Utils.decrypt(privateKeyStr, password);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RenException(ErrorCode.SM2_DECRYPT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分离验证码和密码:前5位是验证码,后面是密码
|
||||||
|
if (decryptedContent.length() > 5) {
|
||||||
|
String embeddedCaptcha = decryptedContent.substring(0, 5);
|
||||||
|
String actualPassword = decryptedContent.substring(5);
|
||||||
|
|
||||||
|
// 验证嵌入的验证码是否正确
|
||||||
|
boolean embeddedCaptchaValid = captchaService.validate(dto.getCaptchaId(), embeddedCaptcha, true);
|
||||||
|
if (!embeddedCaptchaValid) {
|
||||||
|
throw new RenException(ErrorCode.SMS_CAPTCHA_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
dto.setPassword(actualPassword);
|
||||||
|
} else {
|
||||||
|
throw new RenException(ErrorCode.SM2_DECRYPT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
sysUserService.changePasswordDirectly(userDTO.getId(), dto.getPassword());
|
sysUserService.changePasswordDirectly(userDTO.getId(), dto.getPassword());
|
||||||
return new Result<>();
|
return new Result<>();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,10 @@ public class RetrievePasswordDTO implements Serializable {
|
|||||||
@NotBlank(message = "{sysuser.password.require}")
|
@NotBlank(message = "{sysuser.password.require}")
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
|
@Schema(description = "图形验证码ID")
|
||||||
|
@NotBlank(message = "{sysuser.uuid.require}")
|
||||||
|
private String captchaId;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -183,7 +183,8 @@ export default {
|
|||||||
.data({
|
.data({
|
||||||
phone: passwordData.phone,
|
phone: passwordData.phone,
|
||||||
code: passwordData.code,
|
code: passwordData.code,
|
||||||
password: passwordData.password
|
password: passwordData.password,
|
||||||
|
captchaId: passwordData.captchaId
|
||||||
})
|
})
|
||||||
.success((res) => {
|
.success((res) => {
|
||||||
RequestService.clearRequestTime();
|
RequestService.clearRequestTime();
|
||||||
|
|||||||
@@ -101,7 +101,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import Api from '@/apis/api';
|
import Api from '@/apis/api';
|
||||||
import VersionFooter from '@/components/VersionFooter.vue';
|
import VersionFooter from '@/components/VersionFooter.vue';
|
||||||
import { getUUID, goToPage, showDanger, showSuccess, validateMobile } from '@/utils';
|
import { getUUID, goToPage, showDanger, showSuccess, validateMobile, sm2Encrypt } from '@/utils';
|
||||||
import { mapState } from 'vuex';
|
import { mapState } from 'vuex';
|
||||||
|
|
||||||
// 导入语言切换功能
|
// 导入语言切换功能
|
||||||
@@ -115,7 +115,8 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
...mapState({
|
...mapState({
|
||||||
allowUserRegister: state => state.pubConfig.allowUserRegister,
|
allowUserRegister: state => state.pubConfig.allowUserRegister,
|
||||||
mobileAreaList: state => state.pubConfig.mobileAreaList
|
mobileAreaList: state => state.pubConfig.mobileAreaList,
|
||||||
|
sm2PublicKey: state => state.pubConfig.sm2PublicKey
|
||||||
}),
|
}),
|
||||||
canSendMobileCaptcha() {
|
canSendMobileCaptcha() {
|
||||||
return this.countdown === 0 && validateMobile(this.form.mobile, this.form.areaCode);
|
return this.countdown === 0 && validateMobile(this.form.mobile, this.form.areaCode);
|
||||||
@@ -229,10 +230,23 @@ export default {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 加密密码
|
||||||
|
let encryptedPassword;
|
||||||
|
try {
|
||||||
|
// 拼接图形验证码和新密码进行加密
|
||||||
|
const captchaAndPassword = this.form.captcha + this.form.newPassword;
|
||||||
|
encryptedPassword = sm2Encrypt(this.sm2PublicKey, captchaAndPassword);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("密码加密失败:", error);
|
||||||
|
showDanger(this.$t('sm2.encryptionFailed'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Api.user.retrievePassword({
|
Api.user.retrievePassword({
|
||||||
phone: this.form.areaCode + this.form.mobile,
|
phone: this.form.areaCode + this.form.mobile,
|
||||||
password: this.form.newPassword,
|
password: encryptedPassword,
|
||||||
code: this.form.mobileCaptcha
|
code: this.form.mobileCaptcha,
|
||||||
|
captchaId: this.form.captchaId
|
||||||
}, (res) => {
|
}, (res) => {
|
||||||
showSuccess(this.$t('retrievePassword.passwordUpdateSuccess'));
|
showSuccess(this.$t('retrievePassword.passwordUpdateSuccess'));
|
||||||
goToPage('/login');
|
goToPage('/login');
|
||||||
|
|||||||
Reference in New Issue
Block a user