3.1.5 • Published 7 months ago

@logto/node v3.1.5

Weekly downloads
-
License
MIT
Repository
github
Last release
7 months ago

Logto Node.js SDK

Version Build Status Codecov

The Logto Node.js SDK written in TypeScript.

Table of Contents

Installation

Using npm

npm install @logto/node

Using yarn

yarn add @logto/node

Using pnpm

pnpm add @logto/node

What is this and how does it work?

As the name suggests, Logto Node.js SDK is the foundation of all Logto SDKs that run in Node.js (Express, Next.js, etc.). @logto/node extends @logto/client and provides a Node.js specific implementation of the client adapters:

  • Implements requester by using package node-fetch.
  • Implements generateCodeChallenge, generateCodeVerifier, generateState methods by using crypto.

Usually, you are not expected to use it directly in your application, but instead choosing a framework specific SDK that built on top of it. We have already released a set of official SDKs to accelerate your integration. Check this out and get started!

How to create your own SDK from scratch?

If Logto does not support your traditional web framework and you want to create your own SDK from scratch, we recommend checking out the SDK specification first. You can also refer to our Express SDK and Next.js SDK to learn more about the implementation details.

Prerequisites

  • Basic understanding of Node.js and TypeScript
  • Familiarity with your target web framework
  • Understanding of OAuth 2.0 and OpenID Connect concepts

Step 1: Setup the project

Prepare your project by installing @logto/node as the dependency.

Step 2: Implement store adapter

The store adapter is used to store the Logto session information. In most cases, we recommend using cookie-based storage to store the session information.

// storage.ts
import { CookieStorage } from '@logto/node';

export const storage = new CookieStorage({
  encryptionKey: '<your-encryption-key>',
  cookieKey: `<logto_app_xxx>`,
  isSecure: false, // Set to true if you are using HTTPS
  getCookie: (name) => {
    // Example usage, get cookie from the request, depends on your framework
    return request.cookies[name] ?? '';
  },
  setCookie: (name, value, options) => {
    // Example usage, set cookie to the response, depends on your framework
    response.setHeader('Set-Cookie', serialize(name, value, options));
  },
});

This will wrap the session data, encrypt it with the encryption key, and store it in the cookie directly.

But the cookie size is limited, so you may need to use external storage like Redis or memory cache to store the session information. Especially when you are using organization features, the session information will be quite large.

// storage.ts
import { CookieStorage } from '@logto/node';

class RedisSessionWrapper implements SessionWrapper {
  constructor(private readonly redis: Redis) {}

  async wrap(data: unknown, _key: string): Promise<string> {
    const sessionId = randomUUID();
    await this.redis.set(`logto_session_${sessionId}`, JSON.stringify(data));
    return sessionId;
  }

  async unwrap(value: string, _key: string): Promise<SessionData> {
    if (!value) {
      return {};
    }

    const data = await this.redis.get(`logto_session_${value}`);
    return JSON.parse(data);
  }
}

export const storage = new CookieStorage({
  cookieKey: `<logto_app_xxx>`,
  sessionWrapper: new RedisSessionWrapper(redis),
  isSecure: false, // Set to true if you are using HTTPS
  getCookie: (name) => {
    // Example usage, get cookie from the request, depends on your framework
    return request.cookies[name] ?? '';
  },
  setCookie: (name, value, options) => {
    // Example usage, set cookie to the response, depends on your framework
    response.setHeader('Set-Cookie', serialize(name, value, options));
  },
});

Step 3: Implement navigation adapter and create the client

Continue to prepare the navigation adapter and create the client. You need to implement the "redirect" function to redirect the user to the Logto sign-in page.

// client.ts
import { NodeClient } from '@logto/node';
import { config } from './config';
import { storage } from './storage';

export const client = new NodeClient({
  ...config,
  storage,
  navigate: (url) => {
    // Example usage, navigate to the url, depends on your framework
    response.redirect(url);
  },
});

Step 4: Use the client to sign in

You can now trigger the sign-in flow by calling the signIn method.

// app.ts
import { client } from './client';

await client.signIn({
  redirectUri: 'http://localhost:3000/callback',
});

Step 5: Handle the sign-in callback

You need to handle the sign-in callback by calling the signInCallback method.

// app.ts
import { client } from './client';

// You'll need to pass the full url to the callback handler,
// it depends on your framework to get the url.
await client.handleSignInCallback(`${request.url}`);

// After handling the callback, the user is signed in,
// information stored in the storage adapter we created earlier,
// you can now redirect the user to the home page.
response.redirect('/');

Step 6: Implement sign out and other methods

You can now implement the sign out and other methods by referring to our example implementation in other frameworks.

Step 7: Retrieve user information and protect resources

You can call the getContext method to retrieve the user information and protect your resources based on the context.

// app.ts
import { client } from './client';

const { isAuthenticated, claims } = await client.getContext();

if (!isAuthenticated) {
  // The user is not signed in, redirect to the sign-in page.
  // protect the resource from being accessed by unauthenticated users.
  response.redirect('/sign-in');
}

// The user is signed in, you can now do something with the user information.
console.log(claims);

Awesome unofficial SDKs

We have a list of awesome implementations of Logto SDK:

We are grateful for the amazing Logto community!

Resources

Website Docs Discord

3.0.3

1 year ago

3.1.3

8 months ago

3.1.1

10 months ago

3.1.0

1 year ago

3.1.5

7 months ago

3.1.4

8 months ago

2.5.8

1 year ago

2.5.7

1 year ago

2.5.6

1 year ago

2.5.2

1 year ago

2.5.1

2 years ago

2.5.4

1 year ago

2.5.3

1 year ago

2.5.5

1 year ago

2.5.0

2 years ago

2.4.7

2 years ago

2.4.5

2 years ago

2.4.6

2 years ago

2.4.4

2 years ago

2.4.3

2 years ago

2.4.2

2 years ago

2.4.1

2 years ago

2.4.0

2 years ago

2.3.0

2 years ago

2.2.2

2 years ago

2.2.1

2 years ago

2.1.2

2 years ago

2.2.0

2 years ago

2.1.1

3 years ago

2.1.0

3 years ago

1.1.1

3 years ago

1.1.0

3 years ago

1.0.0

3 years ago

1.1.2

3 years ago

2.0.0

3 years ago

1.0.0-rc.0

3 years ago

1.0.0-beta.15

3 years ago

1.0.0-beta.13

3 years ago

1.0.0-beta.14

3 years ago

1.0.0-beta.11

3 years ago

1.0.0-beta.12

3 years ago

1.0.0-beta.10

3 years ago

1.0.0-beta.9

3 years ago

1.0.0-beta.6

3 years ago

1.0.0-beta.7

3 years ago

1.0.0-beta.8

3 years ago

1.0.0-beta.3

3 years ago

1.0.0-beta.4

3 years ago

1.0.0-beta.5

3 years ago

1.0.0-beta.2

3 years ago

1.0.0-beta.0

3 years ago