A node.js library for performing FIDO 2.0 / WebAuthn server functionality
See the codeA library for performing FIDO 2.0 / WebAuthn server functionality
This library contains all the functionality necessary for implementing a full FIDO2 / WebAuthn server. It intentionally does not implement any kind of networking protocol (e.g. - REST endpoints) so that it can remain independent of any messaging protocols.
There are four primary functions:
There is also an extension point for adding new attestation formats.
Full documentation can be found here.
For working examples see OWASP Single Sign-On and / or webauthn.io
require) and ESM (import) nativelynpm install fido2-lib --save
const { Fido2Lib } = require("fido2-lib");
import { Fido2Lib } from "fido2-lib";
Import dist/main.js from a trusted source. Below is only an example, using the official deno.land repository.
It is recommended to enable integrity checking.
import { Fido2Lib } from "https://deno.land/x/fido2@$VERSION/dist/main.js";
Firstly, you need to set up a import map. Put the following lines into your import map.
{
"imports": {
"fido2-lib": "https://deno.land/x/fido2@$VERSION/dist/main.js"
}
}
Then you can import the library like this:
// @deno-types="https://deno.land/x/fido2@$VERSION/types/main.d.ts"
import { Fido2Lib } from "fido2-lib";
Don't forget to replace $VERSION with the specific version. You can find the latest version by checking the redirection of deno.land/x/fido2/dist/main.js and deno.land/x/fido2/types/main.d.ts.
Instantiate Library (Complex):
// could also use one or more of the options below,
// which just makes the options calls easier later on:
const f2l = new Fido2Lib({
timeout: 42,
rpId: "example.com",
rpName: "ACME",
rpIcon: "https://example.com/logo.png",
challengeSize: 128,
attestation: "none",
cryptoParams: [-7, -257],
authenticatorAttachment: "platform",
authenticatorRequireResidentKey: false,
authenticatorUserVerification: "required"
});
Registration:
const registrationOptions = await f2l.attestationOptions();
// make sure to add registrationOptions.user.id and registrationOptions.user.name
// save the challenge in the session information...
// send registrationOptions to client and pass them in to `navigator.credentials.create()`...
// get response back from client (clientAttestationResponse)
const attestationExpectations = {
challenge: "33EHav-jZ1v9qwH783aU-j0ARx6r5o-YHh-wd7C6jPbd7Wh6ytbIZosIIACehwf9-s6hXhySHO-HHUjEwZS29w",
origin: "https://localhost:8443",
factor: "either"
};
const regResult = await f2l.attestationResult(clientAttestationResponse, attestationExpectations); // will throw on error
// registration complete!
// save publicKey and counter from regResult to user's info for future authentication calls
Authentication:
const authnOptions = await f2l.assertionOptions();
// add allowCredentials to limit the number of allowed credential for the authentication process. For further details refer to webauthn specs: (https://www.w3.org/TR/webauthn-2/#dom-publickeycredentialrequestoptions-allowcredentials).
// save the challenge in the session information...
// send authnOptions to client and pass them in to `navigator.credentials.get()`...
// get response back from client (clientAssertionResponse)
const assertionExpectations = {
// Remove the following comment if allowCredentials has been added into authnOptions so the credential received will be validate against allowCredentials array.
// allowCredentials: [{
// id: "lTqW8H/lHJ4yT0nLOvsvKgcyJCeO8LdUjG5vkXpgO2b0XfyjLMejRvW5oslZtA4B/GgkO/qhTgoBWSlDqCng4Q==",
// type: "public-key",
// transports: ["usb"]
// }],
challenge: "eaTyUNnyPDDdK8SNEgTEUvz1Q8dylkjjTimYd5X7QAo-F8_Z1lsJi3BilUpFZHkICNDWY8r9ivnTgW7-XZC3qQ",
origin: "https://localhost:8443",
factor: "either",
publicKey: "-----BEGIN PUBLIC KEY-----\n" +
"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAERez9aO2wBAWO54MuGbEqSdWahSnG\n" +
"MAg35BCNkaE3j8Q+O/ZhhKqTeIKm7El70EG6ejt4sg1ZaoQ5ELg8k3ywTg==\n" +
"-----END PUBLIC KEY-----\n",
prevCounter: 362
};
const authnResult = await f2l.assertionResult(clientAssertionResponse, assertionExpectations); // will throw on error
// authentication complete!
For a real-life example, refer to OWASP Single Sign-On.
It's recommended to have both Deno (>=1.20) and Node 16-18 available to be able to run all checks and tests.
Please run npm run lint, npm run test and deno task test before committing, to make sure every test and check passes.
See package.json for available npm scripts, and deno.jsonc for available Deno tasks.
Make sure to add tests if you add new features.
Important: Do not stage/commit dist/main.js and dist/main.cjs. These are generated and committed automatically by the CI-pipeline.
When adding, removing or updating dependencies, start out with npm as usual. Then update import_map.json to the same versions shown by npm list, and run deno task update-deps to update the Deno lock-file.
When you're finished with the changes, create a pull request.
Work for this project was supported by Adam Power.
Overall
Maintained
Code review
Contributors
npm
Latest release
Releases this year
450 followers · starred Oct 2018
1,484 followers · starred May 2022
45,440 followers · starred Aug 2022
2,200 followers · starred Jan 2023
A node.js library for performing FIDO 2.0 / WebAuthn server functionality
See the codeA library for performing FIDO 2.0 / WebAuthn server functionality
This library contains all the functionality necessary for implementing a full FIDO2 / WebAuthn server. It intentionally does not implement any kind of networking protocol (e.g. - REST endpoints) so that it can remain independent of any messaging protocols.
There are four primary functions:
There is also an extension point for adding new attestation formats.
Full documentation can be found here.
For working examples see OWASP Single Sign-On and / or webauthn.io
require) and ESM (import) nativelynpm install fido2-lib --save
const { Fido2Lib } = require("fido2-lib");
import { Fido2Lib } from "fido2-lib";
Import dist/main.js from a trusted source. Below is only an example, using the official deno.land repository.
It is recommended to enable integrity checking.
import { Fido2Lib } from "https://deno.land/x/fido2@$VERSION/dist/main.js";
Firstly, you need to set up a import map. Put the following lines into your import map.
{
"imports": {
"fido2-lib": "https://deno.land/x/fido2@$VERSION/dist/main.js"
}
}
Then you can import the library like this:
// @deno-types="https://deno.land/x/fido2@$VERSION/types/main.d.ts"
import { Fido2Lib } from "fido2-lib";
Don't forget to replace $VERSION with the specific version. You can find the latest version by checking the redirection of deno.land/x/fido2/dist/main.js and deno.land/x/fido2/types/main.d.ts.
Instantiate Library (Complex):
// could also use one or more of the options below,
// which just makes the options calls easier later on:
const f2l = new Fido2Lib({
timeout: 42,
rpId: "example.com",
rpName: "ACME",
rpIcon: "https://example.com/logo.png",
challengeSize: 128,
attestation: "none",
cryptoParams: [-7, -257],
authenticatorAttachment: "platform",
authenticatorRequireResidentKey: false,
authenticatorUserVerification: "required"
});
Registration:
const registrationOptions = await f2l.attestationOptions();
// make sure to add registrationOptions.user.id and registrationOptions.user.name
// save the challenge in the session information...
// send registrationOptions to client and pass them in to `navigator.credentials.create()`...
// get response back from client (clientAttestationResponse)
const attestationExpectations = {
challenge: "33EHav-jZ1v9qwH783aU-j0ARx6r5o-YHh-wd7C6jPbd7Wh6ytbIZosIIACehwf9-s6hXhySHO-HHUjEwZS29w",
origin: "https://localhost:8443",
factor: "either"
};
const regResult = await f2l.attestationResult(clientAttestationResponse, attestationExpectations); // will throw on error
// registration complete!
// save publicKey and counter from regResult to user's info for future authentication calls
Authentication:
const authnOptions = await f2l.assertionOptions();
// add allowCredentials to limit the number of allowed credential for the authentication process. For further details refer to webauthn specs: (https://www.w3.org/TR/webauthn-2/#dom-publickeycredentialrequestoptions-allowcredentials).
// save the challenge in the session information...
// send authnOptions to client and pass them in to `navigator.credentials.get()`...
// get response back from client (clientAssertionResponse)
const assertionExpectations = {
// Remove the following comment if allowCredentials has been added into authnOptions so the credential received will be validate against allowCredentials array.
// allowCredentials: [{
// id: "lTqW8H/lHJ4yT0nLOvsvKgcyJCeO8LdUjG5vkXpgO2b0XfyjLMejRvW5oslZtA4B/GgkO/qhTgoBWSlDqCng4Q==",
// type: "public-key",
// transports: ["usb"]
// }],
challenge: "eaTyUNnyPDDdK8SNEgTEUvz1Q8dylkjjTimYd5X7QAo-F8_Z1lsJi3BilUpFZHkICNDWY8r9ivnTgW7-XZC3qQ",
origin: "https://localhost:8443",
factor: "either",
publicKey: "-----BEGIN PUBLIC KEY-----\n" +
"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAERez9aO2wBAWO54MuGbEqSdWahSnG\n" +
"MAg35BCNkaE3j8Q+O/ZhhKqTeIKm7El70EG6ejt4sg1ZaoQ5ELg8k3ywTg==\n" +
"-----END PUBLIC KEY-----\n",
prevCounter: 362
};
const authnResult = await f2l.assertionResult(clientAssertionResponse, assertionExpectations); // will throw on error
// authentication complete!
For a real-life example, refer to OWASP Single Sign-On.
It's recommended to have both Deno (>=1.20) and Node 16-18 available to be able to run all checks and tests.
Please run npm run lint, npm run test and deno task test before committing, to make sure every test and check passes.
See package.json for available npm scripts, and deno.jsonc for available Deno tasks.
Make sure to add tests if you add new features.
Important: Do not stage/commit dist/main.js and dist/main.cjs. These are generated and committed automatically by the CI-pipeline.
When adding, removing or updating dependencies, start out with npm as usual. Then update import_map.json to the same versions shown by npm list, and run deno task update-deps to update the Deno lock-file.
When you're finished with the changes, create a pull request.
Work for this project was supported by Adam Power.
Overall
Maintained
Code review
Contributors
npm
Latest release
Releases this year
450 followers · starred Oct 2018
1,484 followers · starred May 2022
45,440 followers · starred Aug 2022
2,200 followers · starred Jan 2023