fix: 修复支付宝签名时错误排除 sign_type 导致 invalid-signature
支付宝验签字符串包含 sign_type 字段,但 generateSign 错误地 将 sign_type 与 sign 一起排除。只需排除 sign,保留 sign_type。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -44,11 +44,16 @@ describe('Alipay RSA2 Sign', () => {
|
|||||||
expect(sign1).toBe(sign2);
|
expect(sign1).toBe(sign2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should filter out sign and sign_type fields', () => {
|
it('should filter out sign field but keep sign_type', () => {
|
||||||
const paramsWithSign = { ...testParams, sign: 'old_sign', sign_type: 'RSA2' };
|
const paramsWithSign = { ...testParams, sign: 'old_sign' };
|
||||||
const sign1 = generateSign(testParams, privateKey);
|
const sign1 = generateSign(testParams, privateKey);
|
||||||
const sign2 = generateSign(paramsWithSign, privateKey);
|
const sign2 = generateSign(paramsWithSign, privateKey);
|
||||||
expect(sign1).toBe(sign2);
|
expect(sign1).toBe(sign2);
|
||||||
|
|
||||||
|
// sign_type should be included in signing
|
||||||
|
const paramsWithSignType = { ...testParams, sign_type: 'RSA2' };
|
||||||
|
const sign3 = generateSign(paramsWithSignType, privateKey);
|
||||||
|
expect(sign3).not.toBe(sign1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should filter out empty values', () => {
|
it('should filter out empty values', () => {
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ export function pageExecute(
|
|||||||
|
|
||||||
params.sign = generateSign(params, env.ALIPAY_PRIVATE_KEY);
|
params.sign = generateSign(params, env.ALIPAY_PRIVATE_KEY);
|
||||||
|
|
||||||
const query = new URLSearchParams({ ...params, sign_type: 'RSA2' }).toString();
|
const query = new URLSearchParams(params).toString();
|
||||||
return `${GATEWAY}?${query}`;
|
return `${GATEWAY}?${query}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,7 +72,6 @@ export async function execute<T extends AlipayResponse>(
|
|||||||
};
|
};
|
||||||
|
|
||||||
params.sign = generateSign(params, env.ALIPAY_PRIVATE_KEY);
|
params.sign = generateSign(params, env.ALIPAY_PRIVATE_KEY);
|
||||||
params.sign_type = 'RSA2';
|
|
||||||
|
|
||||||
const response = await fetch(GATEWAY, {
|
const response = await fetch(GATEWAY, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
|||||||
@@ -14,9 +14,7 @@ function formatPublicKey(key: string): string {
|
|||||||
/** 生成 RSA2 签名 */
|
/** 生成 RSA2 签名 */
|
||||||
export function generateSign(params: Record<string, string>, privateKey: string): string {
|
export function generateSign(params: Record<string, string>, privateKey: string): string {
|
||||||
const filtered = Object.entries(params)
|
const filtered = Object.entries(params)
|
||||||
.filter(
|
.filter(([key, value]) => key !== 'sign' && value !== '' && value !== undefined && value !== null)
|
||||||
([key, value]) => key !== 'sign' && key !== 'sign_type' && value !== '' && value !== undefined && value !== null,
|
|
||||||
)
|
|
||||||
.sort(([a], [b]) => a.localeCompare(b));
|
.sort(([a], [b]) => a.localeCompare(b));
|
||||||
|
|
||||||
const signStr = filtered.map(([key, value]) => `${key}=${value}`).join('&');
|
const signStr = filtered.map(([key, value]) => `${key}=${value}`).join('&');
|
||||||
@@ -29,9 +27,7 @@ export function generateSign(params: Record<string, string>, privateKey: string)
|
|||||||
/** 用支付宝公钥验证签名 */
|
/** 用支付宝公钥验证签名 */
|
||||||
export function verifySign(params: Record<string, string>, alipayPublicKey: string, sign: string): boolean {
|
export function verifySign(params: Record<string, string>, alipayPublicKey: string, sign: string): boolean {
|
||||||
const filtered = Object.entries(params)
|
const filtered = Object.entries(params)
|
||||||
.filter(
|
.filter(([key, value]) => key !== 'sign' && value !== '' && value !== undefined && value !== null)
|
||||||
([key, value]) => key !== 'sign' && key !== 'sign_type' && value !== '' && value !== undefined && value !== null,
|
|
||||||
)
|
|
||||||
.sort(([a], [b]) => a.localeCompare(b));
|
.sort(([a], [b]) => a.localeCompare(b));
|
||||||
|
|
||||||
const signStr = filtered.map(([key, value]) => `${key}=${value}`).join('&');
|
const signStr = filtered.map(([key, value]) => `${key}=${value}`).join('&');
|
||||||
|
|||||||
Reference in New Issue
Block a user