OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

Getting No data error on verifying Authentication using passkey using SimpleWebAuthn and Node.js and react.js

  • Thread starter Thread starter Nobil Gautam
  • Start date Start date
N

Nobil Gautam

Guest
I am trying to use my passkey for login in my react.js app using node.js for backend and using MongoDB for my database.

following is my backend code:

Code:
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);
  }
}

and following is my code to login in backend:

Code:
const generateLoginOptions = async (req, res) => {
  console.log("generate login options called ---------------------->", req.body);
  try {
    const userTofind = await user.findOne({ username: req.body.username });
    if (!userTofind) {
      return res.status(404).json({ message: 'User not found' });
    } else {
      console.log("user found for generating login options ------------------->");
    }

    const loginOptions = await SimpleWebAuthnServer.generateAuthenticationOptions({
      rpID: 'localhost',
    });

    console.log("login options from backend: ----------------", loginOptions);
    await user.findOneAndUpdate(
      { username: req.body.username },
      { challenge: loginOptions.challenge }
    );

    res.json({ options: loginOptions });
  } catch (e) {
    console.error(e);
    res.status(500).json({ message: 'Internal Server Error' });
  }
};

const verifyLogin = async (req, res) => {
  console.log("verify login called ----------------> ", req.body);
  try {
    const userToLogin = await user.findOne({ username: req.body.username });
    if (!userToLogin) {
      return res.status(404).json({ message: 'User not found' });
    }

    const expectedChallenge = userToLogin.challenge;
    console.log("this is your expected challenge: ---------------------" , expectedChallenge);
    console.log("this is for cred testing -----------> ",req.body.cred)
    console.log("the passkey publicKey: =------------->", userToLogin.passkey);
    const verification = await SimpleWebAuthnServer.verifyAuthenticationResponse({
      response: req.body.cred,
      expectedChallenge: expectedChallenge,
      expectedOrigin: 'http://localhost:3000',
      expectedRPID: 'localhost',
      authenticator: {
        credentialID: userToLogin.passkey.credentialID,
        credentialPublicKey: userToLogin.passkey.credentialPublicKey,
        counter: userToLogin.passkey.counter,
      },
    });

    if (!verification.verified) return res.json({ error: 'could not verify' });
    const token = jwt.sign({ username: userToLogin.username, role: userToLogin.role }, "everidoor", {
      expiresIn: "5h",
    });
    if (result.role == "advertiser" || result.role == "display-provider") {
      console.log("------------- token is:>", result.role);
      res.status(200).send({
        Message: "Login Successful",
        role: result.role,
        DpUsername: result.DpUsername,
        cid: result.customerId,
        pin: result.pin,
        token: token,
        verified: true,
      });
    } else {
      res.status(202).send({
        Message: "Login Successful",
        role: result.role,
        DpUsername: result.DpUsername,
        loginCount: result.loginCount,
        token: token,
        verified: true,
      });
    }
  } catch (e) {
    console.error(e);
    res.status(500).json({ message: 'Internal Server Error' });
  }
};

I am handling the logging in my frontend component as follows:

Code:
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");
      }
    };

whenever I am trying to log in, the following error shows up in my backend server:

Code:
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

I am doing everything according to official documentation here: https://simplewebauthn.dev/docs/packages/server

please help me

<p>I am trying to use my passkey for login in my react.js app using node.js for backend and using MongoDB for my database.</p>
<p>following is my backend code:</p>
<pre><code>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);
}
}
</code></pre>
<p>and following is my code to login in backend:</p>
<pre><code>const generateLoginOptions = async (req, res) => {
console.log("generate login options called ---------------------->", req.body);
try {
const userTofind = await user.findOne({ username: req.body.username });
if (!userTofind) {
return res.status(404).json({ message: 'User not found' });
} else {
console.log("user found for generating login options ------------------->");
}

const loginOptions = await SimpleWebAuthnServer.generateAuthenticationOptions({
rpID: 'localhost',
});

console.log("login options from backend: ----------------", loginOptions);
await user.findOneAndUpdate(
{ username: req.body.username },
{ challenge: loginOptions.challenge }
);

res.json({ options: loginOptions });
} catch (e) {
console.error(e);
res.status(500).json({ message: 'Internal Server Error' });
}
};

const verifyLogin = async (req, res) => {
console.log("verify login called ----------------> ", req.body);
try {
const userToLogin = await user.findOne({ username: req.body.username });
if (!userToLogin) {
return res.status(404).json({ message: 'User not found' });
}

const expectedChallenge = userToLogin.challenge;
console.log("this is your expected challenge: ---------------------" , expectedChallenge);
console.log("this is for cred testing -----------> ",req.body.cred)
console.log("the passkey publicKey: =------------->", userToLogin.passkey);
const verification = await SimpleWebAuthnServer.verifyAuthenticationResponse({
response: req.body.cred,
expectedChallenge: expectedChallenge,
expectedOrigin: 'http://localhost:3000',
expectedRPID: 'localhost',
authenticator: {
credentialID: userToLogin.passkey.credentialID,
credentialPublicKey: userToLogin.passkey.credentialPublicKey,
counter: userToLogin.passkey.counter,
},
});

if (!verification.verified) return res.json({ error: 'could not verify' });
const token = jwt.sign({ username: userToLogin.username, role: userToLogin.role }, "everidoor", {
expiresIn: "5h",
});
if (result.role == "advertiser" || result.role == "display-provider") {
console.log("------------- token is:>", result.role);
res.status(200).send({
Message: "Login Successful",
role: result.role,
DpUsername: result.DpUsername,
cid: result.customerId,
pin: result.pin,
token: token,
verified: true,
});
} else {
res.status(202).send({
Message: "Login Successful",
role: result.role,
DpUsername: result.DpUsername,
loginCount: result.loginCount,
token: token,
verified: true,
});
}
} catch (e) {
console.error(e);
res.status(500).json({ message: 'Internal Server Error' });
}
};
</code></pre>
<p>I am handling the logging in my frontend component as follows:</p>
<pre><code>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");
}
};
</code></pre>
<p>whenever I am trying to log in, the following error shows up in my backend server:</p>
<pre><code>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
</code></pre>
<p>I am doing everything according to official documentation here: <a href="https://simplewebauthn.dev/docs/packages/server" rel="nofollow noreferrer">https://simplewebauthn.dev/docs/packages/server</a></p>
<p>please help me</p>
 

Latest posts

Top