diff --git a/packages/ui/certd-client/src/views/certd/mine/user-profile.vue b/packages/ui/certd-client/src/views/certd/mine/user-profile.vue index 3c0e2a348..cd0ccf4c5 100644 --- a/packages/ui/certd-client/src/views/certd/mine/user-profile.vue +++ b/packages/ui/certd-client/src/views/certd/mine/user-profile.vue @@ -278,20 +278,22 @@ async function doRegisterPasskey(deviceName: string) { // type: "public-key", // })); - const credential = await (navigator.credentials as any).create({ - publicKey: { - challenge: Uint8Array.from(atob(options.challenge.replace(/-/g, "+").replace(/_/g, "/")), c => c.charCodeAt(0)), - rp: options.rp, - pubKeyCredParams: options.pubKeyCredParams, - timeout: options.timeout || 60000, - attestation: options.attestation, - // excludeCredentials: excludeCredentials, - user: { - id: new TextEncoder().encode(options.userId + ""), - name: userInfo.value.username, - displayName: deviceName, - }, + const publicKey = { + challenge: Uint8Array.from(atob(options.challenge.replace(/-/g, "+").replace(/_/g, "/")), c => c.charCodeAt(0)), + rp: options.rp, + pubKeyCredParams: options.pubKeyCredParams, + timeout: options.timeout || 60000, + attestation: options.attestation, + // excludeCredentials: excludeCredentials, + user: { + id: new TextEncoder().encode(options.userId + ""), + name: userInfo.value.username, + displayName: deviceName, }, + }; + console.log("passkey register publicKey:", publicKey); + const credential = await (navigator.credentials as any).create({ + publicKey, }); if (!credential) { diff --git a/packages/ui/certd-server/src/modules/login/service/passkey-service.ts b/packages/ui/certd-server/src/modules/login/service/passkey-service.ts index 23feb3956..c6c33686b 100644 --- a/packages/ui/certd-server/src/modules/login/service/passkey-service.ts +++ b/packages/ui/certd-server/src/modules/login/service/passkey-service.ts @@ -1,4 +1,4 @@ -import { cache } from "@certd/basic"; +import { cache, logger } from "@certd/basic"; import { AuthException, BaseService, SysInstallInfo, SysSettingsService, SysSiteInfo } from "@certd/lib-server"; import { isComm } from "@certd/plus-core"; import { Inject, Provide, Scope, ScopeEnum } from "@midwayjs/core"; @@ -54,14 +54,14 @@ export class PasskeyService extends BaseService { const options = await generateRegistrationOptions({ rpName: rpName, rpID: rpId, - userID: new Uint8Array([userId]), + userID: new TextEncoder().encode(userId + ""), userName: username, userDisplayName: user.nickName || username, timeout: 60000, attestationType: "none", excludeCredentials: [], }); - + logger.info('[passkey] 注册选项:', JSON.stringify(options)); cache.set(`passkey:registration:${options.challenge}`, userId, { ttl: 5 * 60 * 1000, }); @@ -86,16 +86,24 @@ export class PasskeyService extends BaseService { const { rpId, origin } = await this.getRpInfo(); - const verification = await verifyRegistrationResponse({ + let verification: any = null; + const verifyReq = { response, expectedChallenge: challenge, expectedOrigin: origin, expectedRPID: rpId, - }); - + }; + try { + verification = await verifyRegistrationResponse(verifyReq); + } catch (error) { + // 后端验证时 + logger.error('[passkey] 注册验证失败:', JSON.stringify(verifyReq)); + throw new AuthException(`注册验证失败:${error.message || error}`); + } if (!verification.verified) { throw new AuthException("注册验证失败"); } + cache.delete(`passkey:registration:${challenge}`);