我正在尝试使用我的密码登录我的react.js应用程序,使用node.js作为后端,并使用MongoDB作为我的数据库。
以下是我的后端代码:
const registerWebAuthentication = async (req, res) => {
console.log("------------------------>>>>",req.body);
try {
const user = await User.findOne({ username: req.body.username });
console.log("from registerWebauthentication: " + req.body);
if (!user) {
return res.status(404).json({ message: 'User not found' });
}
const challengePayload = await SimpleWebAuthnServer.generateRegistrationOptions({
rpID: 'localhost',
rpName: 'nobil localhost',
userName: user.username,
})
await User.findOneAndUpdate(
{ username: req.body.username },
{ challenge: challengePayload.challenge }
);
return res.json({ options: challengePayload })
} catch (e) {
console.log(e);
}
}
const verifyRegistration = async(req, res) => {
console.log("inside verify registrations ===========>>", req.body);
try {
const user = await User.findOne({ username: req.body.username });
if (!user) {
return res.status(404).json({ message: 'User not found' });
}
const expectedChallenge = user.challenge;
const verification = await SimpleWebAuthnServer.verifyRegistrationResponse({
response: req.body.cred,
expectedChallenge: expectedChallenge,
expectedOrigin: 'http://localhost:3000',
expectedRPID: 'localhost',
});
if (!verification.verified) return res.json({ error: 'could not verify' });
await User.findOneAndUpdate(
{ username: req.body.username },
{ passkey: verification.registrationInfo }
);
return res.json({ verified: true });
} catch (e) {
console.log(e);
}
}
以下是我在后端登录的代码:
const registerWebAuthentication = async (req, res) => {
console.log("------------------------>>>>",req.body);
try {
const user = await User.findOne({ username: req.body.username });
console.log("from registerWebauthentication: " + req.body);
if (!user) {
return res.status(404).json({ message: 'User not found' });
}
const challengePayload = await SimpleWebAuthnServer.generateRegistrationOptions({
rpID: 'localhost',
rpName: 'nobil localhost',
userName: user.username,
})
await User.findOneAndUpdate(
{ username: req.body.username },
{ challenge: challengePayload.challenge }
);
return res.json({ options: challengePayload })
} catch (e) {
console.log(e);
}
}
const verifyRegistration = async(req, res) => {
console.log("inside verify registrations ===========>>", req.body);
try {
const user = await User.findOne({ username: req.body.username });
if (!user) {
return res.status(404).json({ message: 'User not found' });
}
const expectedChallenge = user.challenge;
const verification = await SimpleWebAuthnServer.verifyRegistrationResponse({
response: req.body.cred,
expectedChallenge: expectedChallenge,
expectedOrigin: 'http://localhost:3000',
expectedRPID: 'localhost',
});
if (!verification.verified) return res.json({ error: 'could not verify' });
await User.findOneAndUpdate(
{ username: req.body.username },
{ passkey: verification.registrationInfo }
);
return res.json({ verified: true });
} catch (e) {
console.log(e);
}
}
我正在按如下方式处理前端组件中的日志记录:
const handlePasskeyLogin = async () => {
try {
const res = await Axios.post('/generate-login-options', { username: passkeyUsername });
console.log("following are the options: ", res);
const options = res.data.options;
const loginRes = await startAuthentication(options);
console.log(loginRes);
const verifyRes = await Axios.post('/verify-passkey-login', { username: passkeyUsername, cred: loginRes });
console.log("response from server on verification of passkey login: ", verifyRes);
// if (verifyRes.data.verified) {
// setAdvertiser(verifyRes.data.user);
// setSigned(true);
// navigate("/home");
// } else {
// notify("Passkey login failed");
// }
if(verifyRes.data.role === "display-provider"){
localStorage.setItem("Dp_token", verifyRes?.data?.token);
}
else{
localStorage.setItem("token", verifyRes?.data?.token);
}
console.log(verifyRes?.data?.token);
sessionStorage.setItem("role", verifyRes.data);
localStorage.setItem("Admin", verifyRes.data.DpUsername);
console.error("An error occurred:", verifyRes?.status);
if (verifyRes?.status === 200) {
setAdvertiser(verifyRes.data)
sessionStorage.setItem("role", verifyRes.data.role);
setSigned(true);
navigate("/home");
}
else if (verifyRes?.status === 202) {
setSigned(true);
if (verifyRes.data.role === "Manager") {
sessionStorage.setItem("role", verifyRes.data.role);
navigate("/Manager");
} else if (verifyRes.data.role === "Publisher") {
sessionStorage.setItem("role", verifyRes.data.role);
navigate("/Publisher");
} else if (verifyRes.data.role === "Viewer") {
sessionStorage.setItem("role", verifyRes.data.role);
navigate("/Viewer");
}
}
} catch (error) {
console.error(error);
notify("Error during passkey login");
}
};
每当我尝试登录时,我的后端服务器中都会显示以下错误:
Error: No data
at Object.decodePartialCBOR (C:\Users\nobil\OneDrive\Desktop\MOLOG\EveridoorBackend2.0\node_modules\@levischuck\tiny-cbor\script\cbor\cbor.js:355:15)
at Object.decodeFirst (C:\Users\nobil\OneDrive\Desktop\MOLOG\EveridoorBackend2.0\node_modules\@simplewebauthn\server\script\helpers\iso\isoCBOR.js:25:40)
at decodeCredentialPublicKey (C:\Users\nobil\OneDrive\Desktop\MOLOG\EveridoorBackend2.0\node_modules\@simplewebauthn\server\script\helpers\decodeCredentialPublicKey.js:6:84)
at verifySignature (C:\Users\nobil\OneDrive\Desktop\MOLOG\EveridoorBackend2.0\node_modules\@simplewebauthn\server\script\helpers\verifySignature.js:20:86)
at Object.verifyAuthenticationResponse (C:\Users\nobil\OneDrive\Desktop\MOLOG\EveridoorBackend2.0\node_modules\@simplewebauthn\server\script\authentication\verifyAuthenticationResponse.js:157:66)
at async verifyLogin (C:\Users\nobil\OneDrive\Desktop\MOLOG\EveridoorBackend2.0\controllers\user.controller.js:147:26)
POST /verify-passkey-login 500 52.308 ms - 35
我正在根据此处的官方文档进行所有操作:https://simplewebauthn.dev/docs/packages/server
请帮助我
我认为实施过程中存在一些问题。
您的登录应调用
SimpleWebAuthnServer.generateAuthenticationOptions
而不是 SimpleWebAuthnServer.generateRegistrationOptions
(https://simplewebauthn.dev/docs/advanced/passkeys#generateauthenticationoptions)。与验证部分相同。它应该是 ~.verifyAuthenticationResponse
而不是 ~.verifyRegistrationResponse
(https://simplewebauthn.dev/docs/advanced/passkeys#verifyauthenticationresponse)。
您需要将您为用户保存的 passKeys 详细信息传递给
verifyAuthenticationResponse
,因此它应该如下所示:
const verification = await SimpleWebAuthnServer.verifyRegistrationResponse({
response: req.body.cred,
expectedChallenge: expectedChallenge,
expectedOrigin: 'http://localhost:3000',
expectedRPID: 'localhost',
authenticator: {
credentialID: user.passkey.credentialID,
credentialPublicKey: user.passkey.credentialPublicKey.buffer,
counter: passkey.counter,
transports: passkey.transports
}
});
user.passkey.credentialPublicKey.buffer
(缓冲区)而不是 user.passkey.credentialPublicKey
。 MongoDB 会将 PublicKey 值 (Unit8Array) 保存为 Binary,因此您需要将其转换回来。