Server SDK (Node.js)

Use the PlainKey Server SDK to verify authentication tokens and manage users and passkeys in your Node.js backend.

Author: PlainKey

← Back to server setup alternatives

In your backend, you must verify authentication tokens. The Server SDK is recommended for Node.js projects. This includes if your backend is built with Express, Hono, Fastify, Next.js, Nuxt, SvelteKit etc.

The Server SDK also allows you to manage users and passkeys.

Installation

In the terminal, install the PlainKey server and types packages.

npm install @plainkey/server
npm install @plainkey/types

Initialise

It is recommended to initialise the PlainKey Server SDK in a single location and import it wherever you need it.

This is because the SDK handles access token management internally. If you were to initialise it on every request, the SDK would fetch a new access token on each request.

Having it in a single location will make it fetch new access tokens only when needed, which will make the Server SDK more efficient.

// server/plainKeyServer.ts or similar
import { PlainKeyServer } from "@plainkey/server"

export const plainKeyServer = new PlainKeyServer("YOUR_PROJECT_ID", "YOUR_CLIENT_SECRET")

Verify authentication token

A user is authenticated in the frontend using the Browser SDK. Authentication occurs when the user authenticates with a passkey, but also when a user is first created with a passkey, or when a user adds a new passkey.

In your backend, you must build an endpoint that receives the authentication token and exchanges it for a user session or whatever fits your application. You use the PlainKey Server SDK's .verifyAuthenticationToken() method to verify the token.

On verification success, the SDK returns the user's PlainKey User ID, which you use to find or create the user in your database.

You must store this user ID with your user record. This is your primary reference to the PlainKey user.

After verification and storing the user ID, you continue doing what suits your application. For sign-in, this usually involves creating your own session for the user and returning the session data to the frontend.

Endpoint example: Exchanging authentication token for user session

This shows an endpoint that receives the authentication token and exchanges it for a user login session. The endpoint is used for both sign-in and sign-up.

/**
 * Endpoint handler that receives authentication token and exchanges it for a user session
 */
app.post("/api/auth/exchange", async (request, response) => {
  // In this example, we pass in the authentication token, but also optionally a userName for first signup.
  const { token, userName } = request.body

  if (!token) {
    return response.status(400)
  }

  // 1. Verify authentication token with PlainKey.
  //    On success it returns the PlainKey user ID.
  //    If the token is invalid or expired, it throws an error.
  const { userId: plainKeyUserId } = await plainKeyServer.verifyAuthenticationToken(token)

  // 2. Find or create user in your database
  let user = await findUserByPlainKeyId(plainKeyUserId)

  if (!user) {
    // First time we've seen this user (signup).
    // In this case we'd usually have passed a userName or some identity information to the endpoint.
    if (!userName) {
      return response.status(400)
    }

    user = await createUser({
      plainKeyUserId,
      userName
    })
  }

  // 3. For sign-in: Establish a session for the user
  //    (typically by creating a session and setting a first-party cookie)
  await establishUserSession(response, user.id)

  response.json({ success: true })
})

Starting a new passkey registration from your backend

It is possible to start a new passkey registration from your backend.

(Upcoming feature)

Manage users

The Server SDK provides methods to manage users.

(Upcoming feature)

Manage passkeys

The Server SDK provides methods to manage passkeys.

(Upcoming feature)