Skip to content

Commit abab740

Browse files
committed
perf: 解决非本地环境必须使用https访问的问题
1 parent 92f1dee commit abab740

3 files changed

Lines changed: 46 additions & 4 deletions

File tree

web/playground/src/store/auth.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,10 @@ export const useAuthStore = defineStore('auth', () => {
4242
let userInfo: null | UserInfo = null;
4343
try {
4444
loginLoading.value = true;
45+
4546
const username = String(params?.username ?? '');
4647
const password = String(params?.password ?? '');
4748

48-
// 获取 RSA 临时公钥,前端加密后提交,避免明文密码上传
4949
const rsa = await getLoginRsaKeyApi();
5050
const encryptedPassword = await rsaOaepEncryptBase64(
5151
rsa.publicKey,
@@ -56,7 +56,6 @@ export const useAuthStore = defineStore('auth', () => {
5656
...params,
5757
encryptedPassword,
5858
keyId: rsa.keyId,
59-
// 不发送明文 password
6059
password: undefined,
6160
username,
6261
});
@@ -90,6 +89,21 @@ export const useAuthStore = defineStore('auth', () => {
9089
});
9190
}
9291
}
92+
} catch (e: unknown) {
93+
const isAxios =
94+
typeof e === 'object' &&
95+
e !== null &&
96+
'isAxiosError' in e &&
97+
(e as { isAxiosError?: boolean }).isAxiosError === true;
98+
// Axios 错误通常已由请求拦截器 message.error,避免重复弹窗
99+
if (!isAxios) {
100+
notification.error({
101+
message: '登录失败',
102+
description: e instanceof Error ? e.message : String(e),
103+
duration: 6,
104+
});
105+
}
106+
throw e;
93107
} finally {
94108
loginLoading.value = false;
95109
}

web/playground/src/utils/rsa-oaep.ts

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
/**
2+
* 与后端 `cryptography` RSA-OAEP-SHA256(MGF1-SHA256、label 空)对齐的加密。
3+
* - 安全上下文下优先用 Web Crypto(性能更好)
4+
* - 纯 HTTP + 非 localhost 时无 crypto.subtle,使用 node-forge 纯 JS 实现,仍为非明文传输
5+
*/
6+
import forge from 'node-forge';
7+
18
function pemToArrayBuffer(pem: string): ArrayBuffer {
29
const b64 = pem
310
.replaceAll(/-----(BEGIN|END) PUBLIC KEY-----/g, '')
@@ -19,7 +26,19 @@ function arrayBufferToBase64(buf: ArrayBuffer): string {
1926
return btoa(binary);
2027
}
2128

22-
export async function rsaOaepEncryptBase64(
29+
function rsaOaepEncryptForgeBase64(publicKeyPem: string, plaintext: string): string {
30+
const publicKey = forge.pki.publicKeyFromPem(publicKeyPem);
31+
const encoded = forge.util.encodeUtf8(plaintext);
32+
const encrypted = publicKey.encrypt(encoded, 'RSA-OAEP', {
33+
md: forge.md.sha256.create(),
34+
mgf1: {
35+
md: forge.md.sha256.create(),
36+
},
37+
});
38+
return forge.util.encode64(encrypted);
39+
}
40+
41+
async function rsaOaepEncryptSubtleBase64(
2342
publicKeyPem: string,
2443
plaintext: string,
2544
): Promise<string> {
@@ -39,3 +58,13 @@ export async function rsaOaepEncryptBase64(
3958
);
4059
return arrayBufferToBase64(encrypted);
4160
}
61+
62+
export async function rsaOaepEncryptBase64(
63+
publicKeyPem: string,
64+
plaintext: string,
65+
): Promise<string> {
66+
if (typeof globalThis.crypto?.subtle !== 'undefined') {
67+
return rsaOaepEncryptSubtleBase64(publicKeyPem, plaintext);
68+
}
69+
return rsaOaepEncryptForgeBase64(publicKeyPem, plaintext);
70+
}

web/playground/src/views/_core/authentication/register.vue

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ async function handleSubmit(value: Recordable<any>) {
101101
username: String(value.username || ''),
102102
encryptedPassword,
103103
keyId: rsa.keyId,
104-
// 不发送明文密码
105104
password: undefined,
106105
});
107106
message.success('注册成功,请登录');

0 commit comments

Comments
 (0)