微信小程序登录页面调整
This commit is contained in:
@@ -41,6 +41,10 @@ TRUST_PROXY=true
|
||||
# 微信服务号「网页授权域名」「JS 接口安全域名」均配置 user.runxian.top(仅 1 个名额)。
|
||||
WX_APP_ID=
|
||||
WX_APP_SECRET=
|
||||
# 小程序(code2session / 小程序支付 appid;须与 apps/mini-user/project.config.json 的 appid 一致)
|
||||
# 未配置时回退 WX_APP_ID,若与小程序 appid 不同会导致 invalid code
|
||||
WX_MINI_APP_ID=
|
||||
WX_MINI_APP_SECRET=
|
||||
WECHAT_AUTH_ENABLED=false
|
||||
WECHAT_PAY_ENABLED=false
|
||||
WX_MCH_ID=
|
||||
|
||||
@@ -23,6 +23,9 @@ export class WechatApiProvider implements IWechatProvider {
|
||||
private readonly config = loadAppConfig();
|
||||
private readonly appId = process.env.WX_APP_ID ?? '';
|
||||
private readonly appSecret = process.env.WX_APP_SECRET ?? '';
|
||||
/** 小程序独立凭证;未配置时回退公众号/H5 的 WX_APP_ID(须与开发者工具 appid 一致) */
|
||||
private readonly miniAppId = (process.env.WX_MINI_APP_ID ?? this.appId).trim();
|
||||
private readonly miniAppSecret = (process.env.WX_MINI_APP_SECRET ?? this.appSecret).trim();
|
||||
private readonly mchId = process.env.WX_MCH_ID ?? '';
|
||||
private readonly mchSerialNo = process.env.WX_MCH_SERIAL_NO ?? '';
|
||||
private readonly mchPrivateKey = (process.env.WX_MCH_PRIVATE_KEY ?? '').replace(/\\n/g, '\n');
|
||||
@@ -70,14 +73,21 @@ export class WechatApiProvider implements IWechatProvider {
|
||||
}
|
||||
|
||||
async code2Session(code: string, actorRef?: WechatActorRef): Promise<WechatCodeSession> {
|
||||
const appId = this.miniAppId;
|
||||
const appSecret = this.miniAppSecret;
|
||||
if (!appId || !appSecret) {
|
||||
throw new InternalServerErrorException(
|
||||
'小程序微信登录未配置:请设置 WX_MINI_APP_ID / WX_MINI_APP_SECRET(或与 project.config.json appid 一致)',
|
||||
);
|
||||
}
|
||||
const url = new URL('https://api.weixin.qq.com/sns/jscode2session');
|
||||
url.searchParams.set('appid', this.appId);
|
||||
url.searchParams.set('appid', appId);
|
||||
url.searchParams.set('secret', '***');
|
||||
url.searchParams.set('js_code', code);
|
||||
url.searchParams.set('grant_type', 'authorization_code');
|
||||
const apiUrl = new URL('https://api.weixin.qq.com/sns/jscode2session');
|
||||
apiUrl.searchParams.set('appid', this.appId);
|
||||
apiUrl.searchParams.set('secret', this.appSecret);
|
||||
apiUrl.searchParams.set('appid', appId);
|
||||
apiUrl.searchParams.set('secret', appSecret);
|
||||
apiUrl.searchParams.set('js_code', code);
|
||||
apiUrl.searchParams.set('grant_type', 'authorization_code');
|
||||
const data = await this.fetchJson<{
|
||||
@@ -91,7 +101,7 @@ export class WechatApiProvider implements IWechatProvider {
|
||||
await logWechatAuth(this.prisma, {
|
||||
scene: 'LOGIN',
|
||||
requestUrl: url.toString(),
|
||||
requestBody: { grant_type: 'authorization_code', platform: 'mini' },
|
||||
requestBody: { grant_type: 'authorization_code', platform: 'mini', appId },
|
||||
responseBody: ok
|
||||
? { openid: data.openid, unionid: data.unionid }
|
||||
: { errcode: data.errcode, errmsg: data.errmsg },
|
||||
@@ -101,7 +111,11 @@ export class WechatApiProvider implements IWechatProvider {
|
||||
actorRef,
|
||||
});
|
||||
if (!data.openid) {
|
||||
throw new InternalServerErrorException(data.errmsg || '微信 code2session 失败');
|
||||
const invalidCode = data.errcode === 40029 || /invalid code/i.test(data.errmsg ?? '');
|
||||
const hint = invalidCode
|
||||
? `(后端 appid=${appId},请确认 WX_MINI_APP_ID/SECRET 与小程序 project.config.json 一致;本地可 MOCK_WECHAT=true)`
|
||||
: '';
|
||||
throw new InternalServerErrorException((data.errmsg || '微信 code2session 失败') + hint);
|
||||
}
|
||||
return {
|
||||
openId: data.openid,
|
||||
@@ -284,7 +298,7 @@ export class WechatApiProvider implements IWechatProvider {
|
||||
throw new InternalServerErrorException('请配置 WX_PAY_NOTIFY_URL');
|
||||
}
|
||||
const body = {
|
||||
appid: this.appId,
|
||||
appid: this.miniAppId || this.appId,
|
||||
mchid: this.mchId,
|
||||
description: params.description,
|
||||
out_trade_no: params.orderNo,
|
||||
|
||||
Reference in New Issue
Block a user