npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@point3/logto-module

v1.0.23

Published

포인트3 내부 logto Authentication 모듈입니다

Readme

point3-logto-module

NestJS 기반 Logto 인증/권한 통합 모듈
(서버/클라이언트, M2M, 사용자/역할 관리, OAuth, DI 기반 확장성 제공)


📦 개요

@point3-logto-moduleLogto 인증 시스템을 NestJS 환경에서 손쉽게 통합할 수 있도록 설계된 모듈 번들입니다.
OAuth, M2M(Machine-to-Machine), 사용자/역할 관리, 토큰 검증, 인증 가드 등 인증/권한 관련 기능을 일관된 DI 패턴으로 제공합니다.

동작 모드

LOGTO_CLIENT 환경변수 값에 따라 두 가지 모드로 동작합니다:

  • Stateless 모드 (LOGTO_CLIENT=false 또는 미설정):

    • API 서버와 같이 토큰 검증만 필요한 경우 사용
    • @LogtoProtected() 가드와 LogtoTokenVerifier만 활성화
    • 필수 환경변수: LOGTO_JWKS_URI, LOGTO_AUTH_ISSUER만 필요
  • Stateful 모드 (LOGTO_CLIENT=true):

    • 로그인/로그아웃 처리가 필요한 웹 애플리케이션이나 M2M 통신이 필요한 경우 사용
    • OAuthClient, LogtoM2MClient 등 모든 클라이언트 기능 활성화
    • 추가 환경변수 필요 (OAuth, M2M 관련)

주요 특징

  • 유연한 로깅 연동: 외부 로거 모듈/토큰을 DI로 주입받아, 다양한 로깅 시스템과 쉽게 통합
  • NestJS Dynamic Module 패턴: 환경/구성에 따라 동적으로 모듈 생성
  • Global 모듈 지원: 애플리케이션 전체에서 사용할 수 있는 글로벌 모듈로 설정 가능
  • 실제 서비스에서 검증된 인증/권한 관리 기능: OAuth, M2M, 사용자/역할 관리, 토큰 검증, 인증 가드 등

🏗️ 주요 구성요소

1. LogtoModule (Dynamic Module)

  • 외부에서 로거 모듈과 토큰을 주입받아, Logto 인증/권한 기능을 번들로 제공
  • logto.module.LogtoModule.forLogger(loggerModule, loggerToken, global?) 패턴으로 사용
  • global 파라미터를 true로 설정하면 애플리케이션 전체에서 사용 가능한 글로벌 모듈로 등록

2. 핵심 서비스/토큰

  • OAuthClient: OAuth 인증(로그인/로그아웃 URI, 토큰 발급 등)
  • LogtoM2MClient: 서버 간(M2M) 인증 및 사용자/역할 관리
  • LogtoLoginSession: 세션 기반 로그인 플로우 관리
  • LogtoTokenVerifier: JWT 토큰 검증 및 권한 체크
  • LogtoTokenGuard: NestJS 인증 가드(컨트롤러 보호)
  • LogtoLoggerServiceToken: DI로 주입받는 외부 로거 토큰
  • stateless: 미들웨어/핸들러 기반의 Stateless 인증/인가 유틸리티 및 가드 제공

3. 주요 타입/설정

  • LogtoConfig: 인증/권한 기능을 위한 환경설정 객체
  • Prompt, GrantType: OAuth 표준 파라미터 Enum
  • LogtoUser, LogtoRole 등: 사용자/역할 관리용 타입

⚙️ 설치

npm install @point3/logto-module

🚀 사용법

1. 외부 로거 모듈 준비

// my-logger.module.ts
import { Module } from '@nestjs/common';
import { WinstonLoggerService } from './winston-logger.service';

export const MY_LOGGER_TOKEN = Symbol.for('LOGGER');

@Module({
  providers: [
    {
      provide: MY_LOGGER_TOKEN,
      useClass: WinstonLoggerService,
    },
  ],
  exports: [MY_LOGGER_TOKEN],
})
export class MyLoggerModule {}

2. AppModule에서 LogtoModule 동적 생성

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import * as logto from '@point3/logto-module';
import { MyLoggerModule, MY_LOGGER_TOKEN } from './my-logger.module';

@Module({
  imports: [
    // 환경변수를 먼저 로드
    ConfigModule.forRoot({ isGlobal: true }),
    
    // LogtoModule을 글로벌 모듈로 설정 (세 번째 파라미터를 true로 설정)
    logto.module.LogtoModule.forLogger(MyLoggerModule, MY_LOGGER_TOKEN, true),
  ],
})
export class AppModule {}

3. 서비스 DI 및 사용 예시 (클래식 DI)

import { Injectable, Inject } from '@nestjs/common';
import { client } from '@point3/logto-module';

@Injectable()
export class AuthService {
  constructor(
    @Inject(client.OAuthClientToken)
    private readonly oauthClient: InstanceType<typeof client.OAuthClient>,
    @Inject(client.LogtoM2MClientToken)
    private readonly m2mClient: InstanceType<typeof client.LogtoM2MClient>,
    @Inject(client.LogtoLoginSessionToken)
    private readonly loginSession: InstanceType<typeof client.LogtoLoginSession>,
  ) {}

  // OAuth 로그인 URI 생성
  async loginUri() {
    return this.oauthClient.getSignInURI('admin');
  }

  // M2M 사용자 생성
  async createUser(user) {
    return this.m2mClient.createUser(user);
  }

  // 세션 기반 로그인 플로우 예시
  async sessionLoginFlow(username: string, password: string) {
    const session = await this.loginSession.createSignInSession(username);
    await this.loginSession.verifyPassword(session.sessionId, password);
    // ... 추가 플로우
  }
}

4. stateless 네임스페이스 활용 예시

⚠️ 중요한 주의사항
requiredScopesrequiredRoles에 사용되는 모든 스코프와 역할은 반드시 Logto 관리 콘솔에서 먼저 정의되어야 합니다.

  • 스코프(Scopes): Logto 콘솔의 API Resources → 해당 리소스 → Scopes에서 정의
  • 역할(Roles): Logto 콘솔의 User Management → Roles에서 정의
  • 역할-스코프 연결: 각 역할에 필요한 스코프들을 Logto 콘솔에서 할당

코드에서 사용하는 스코프/역할 이름이 Logto에 정의되지 않았다면 토큰 검증이 실패합니다.

4-1. LogtoProtected 데코레이터를 사용한 라우트 보호

// user.controller.ts
import { Controller, Get } from '@nestjs/common';
import { stateless } from '@point3/logto-module';

@Controller('users')
export class UserController {
  // 기본 토큰 인증만 필요한 경우
  @Get('profile')
  @stateless.LogtoProtected()
  getProfile() {
    return { message: '인증된 사용자만 접근 가능' };
  }

  // 특정 스코프가 필요한 경우
  @Get('admin')
  @stateless.LogtoProtected({
    requiredScopes: ['admin', 'user:read']
  })
  getAdminData() {
    return { message: '관리자 스코프가 필요한 데이터' };
  }

  // 특정 역할이 필요한 경우
  @Get('management')
  @stateless.LogtoProtected({
    requiredRoles: ['superuser', 'management-point3']
  })
  getManagementData() {
    return { message: '관리자 역할이 필요한 데이터' };
  }

  // 스코프와 역할을 모두 요구하는 경우
  @Get('secure')
  @stateless.LogtoProtected({
    requiredScopes: ['admin'],
    requiredRoles: ['superuser']
  })
  getSecureData() {
    return { message: '고급 권한이 필요한 데이터' };
  }
}

4-2. 커스텀 데코레이터로 유저 정보 추출

// user.decorator.ts
import { createParamDecorator, ExecutionContext } from '@nestjs/common';

export const CurrentUser = createParamDecorator(
  (data: unknown, ctx: ExecutionContext) => {
    const request = ctx.switchToHttp().getRequest();
    // LogtoTokenGuard가 request.user에 설정한 사용자 정보 반환
    return request.user;
  },
);

// 컨트롤러에서 사용
@Controller('me')
export class MeController {
  @Get()
  @stateless.LogtoProtected()
  getMe(@CurrentUser() user: any) {
    return {
      userId: user.userId,
      managerId: user.managerId,
      clientId: user.clientId
    };
  }
}

4-3. 전역 가드로 LogtoTokenGuard 등록

// app.module.ts
import { Module } from '@nestjs/common';
import { APP_GUARD } from '@nestjs/core';
import { stateless } from '@point3/logto-module';

@Module({
  providers: [
    {
      provide: APP_GUARD,
      useClass: stateless.LogtoTokenGuard,
    },
  ],
})
export class AppModule {}

4-4. 커스텀 가드에서 LogtoTokenGuard 확장

// custom.guard.ts
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { stateless } from '@point3/logto-module';

@Injectable()
export class CustomLogtoGuard extends stateless.LogtoTokenGuard {
  async canActivate(context: ExecutionContext): Promise<boolean> {
    // 기본 토큰 검증 수행
    const isValid = await super.canActivate(context);
    
    if (!isValid) return false;

    // 추가 커스텀 로직
    const request = context.switchToHttp().getRequest();
    const user = request.user;
    
    // 예: 특정 시간대에만 접근 허용
    const currentHour = new Date().getHours();
    if (currentHour < 9 || currentHour > 18) {
      return false;
    }
    
    return true;
  }
}

4-5. 타입 안전성을 위한 역할 타입 정의

// types/roles.ts
export type UserRole = 'admin' | 'user' | 'moderator';

// 컨트롤러에서 타입 안전하게 사용
@Controller('typed')
export class TypedController {
  @Get('admin-only')
  @stateless.LogtoProtected<UserRole>({
    requiredRoles: ['admin'] // 타입 체크됨
  })
  getAdminData() {
    return { message: '타입 안전한 역할 기반 접근 제어' };
  }
}

🛠️ 주요 기능 및 역할

LogtoModule

  • 외부 로거 모듈/토큰을 받아, 인증/권한 관련 서비스와 가드를 번들로 제공
  • DynamicModule 패턴으로 다양한 환경에 유연하게 적용 가능

OAuthClient

  • OAuth 로그인/로그아웃 URI 생성
  • 인증 코드로 토큰 발급
  • 토큰 해지(로그아웃)

LogtoM2MClient

  • M2M 인증(서버 간 토큰 발급)
  • 사용자/역할 생성, 조회, 수정, 삭제, 할당 등 관리
  • 인증코드 발송/검증, 비밀번호 변경 등 부가 기능

LogtoLoginSession

  • 세션 기반 로그인 플로우(단계별 API 호출)
  • 비밀번호 검증, 사용자 식별, 동의 처리 등

LogtoTokenVerifier

  • JWT 토큰 검증 및 권한 체크
  • 인증 가드(LogtoTokenGuard)에서 활용

stateless

  • 미들웨어/핸들러 기반의 Stateless 인증/인가 유틸리티 및 가드 제공
  • Express/Fastify 등에서 직접 활용 가능한 인증 미들웨어, 데코레이터, 커스텀 가드 등 포함

📝 환경설정 예시 (LogtoConfig)

const config: LogtoConfig = {
  endpoint: 'https://auth.example.com/oidc',
  appId: 'my-client-id',
  appSecret: 'my-client-secret',
  grantType: GrantType.AuthorizationCode,
  scopes: ['openid', 'profile', 'email'],
  resources: ['https://api.example.com'],
  prompt: Prompt.Login,
  redirectUri: 'https://myapp.com/callback',
};

🗂️ 환경변수 목록 및 설명

필수 환경변수 (Stateless/Stateful 모드 공통)

| 환경변수명 | 설명 | 예시 값 | |-----------------------------------|---------------------------------------------------|------------------------------------------| | LOGTO_JWKS_URI | JWT 검증용 JWKS 엔드포인트 | https://auth.example.com/oidc/jwks | | LOGTO_AUTH_ISSUER | JWT 발급자(iss) | https://auth.example.com/oidc |

선택적 환경변수

| 환경변수명 | 설명 | 예시 값 | 필요 조건 | |-----------------------------------|---------------------------------------------------|------------------------------------------|-----------------------------------------| | LOGTO_CLIENT | Stateful 모드 활성화 (클라이언트 기능 사용) | true | 클라이언트 기능 사용 시 | | LOGTO_AUTH_ENDPOINT | Logto 인증 서버 OIDC 엔드포인트 | https://auth.example.com/oidc | LOGTO_CLIENT=true | | LOGTO_CLIENT_ID | OAuth 클라이언트 ID | my-client-id | LOGTO_CLIENT=true | | LOGTO_CLIENT_SECRET | OAuth 클라이언트 시크릿 | my-client-secret | LOGTO_CLIENT=true | | LOGTO_RESOURCES | 접근할 리소스 서버(여러 개일 경우 쉼표로 구분) | https://api.example.com | LOGTO_CLIENT=true | | LOGTO_SCOPES | 요청할 OAuth 스코프(쉼표로 구분) | openid,profile,email | LOGTO_CLIENT=true | | LOGTO_PROMPT | OAuth prompt 파라미터 | login | LOGTO_CLIENT=true | | LOGTO_REDIRECT_URI | 인증 후 리다이렉트될 URI | https://myapp.com/callback | LOGTO_CLIENT=true | | LOGTO_SIGN_IN_URI | 기본 로그인 URI | https://auth.example.com | LOGTO_CLIENT=true | | LOGTO_DASHBOARD_SIGN_IN_URI | 대시보드 로그인 URI(선택) | https://dashboard.example.com | LOGTO_CLIENT=true | | LOGTO_M2M_CLIENT_ID | M2M 인증용 클라이언트 ID | my-m2m-client-id | LOGTO_CLIENT=true & M2M 기능 사용 시 | | LOGTO_M2M_CLIENT_SECRET | M2M 인증용 클라이언트 시크릿 | my-m2m-client-secret | LOGTO_CLIENT=true & M2M 기능 사용 시 | | LOGTO_M2M_RESOURCE | M2M 인증용 리소스 | https://api.example.com | LOGTO_CLIENT=true & M2M 기능 사용 시 | | LOGTO_M2M_API_URL | M2M API 서버의 base URL | https://api.example.com/api | LOGTO_CLIENT=true & M2M 기능 사용 시 |

⚠️ 중요:

  • Stateless 모드(기본값): LOGTO_JWKS_URILOGTO_AUTH_ISSUER만 설정하면 토큰 검증 기능을 사용할 수 있습니다.
  • Stateful 모드: LOGTO_CLIENT=true로 설정하고 OAuth/M2M 관련 환경변수를 추가로 설정해야 합니다.

🧩 확장/커스터마이징

  • 외부 로깅 시스템과의 연동이 필요할 경우, 원하는 로거 모듈/토큰을 DI로 주입
  • 각 서비스별로 NestJS의 DI/Provider 패턴을 그대로 활용 가능
  • 필요시 각 서비스/가드를 직접 DI 받아 커스텀 비즈니스 로직 구현 가능

❓ FAQ

  • Q. 로거 토큰이 다르면 어떻게 하나요?
    forLogger의 두 번째 인자로 원하는 토큰(Symbol)을 넘기면 됩니다.

  • Q. 환경변수 기반 설정은 어떻게 하나요?
    → 각 서비스는 DI로 ConfigService를 받아 환경변수 기반으로 설정을 자동 주입받습니다.

  • Q. 인증/권한 외에 사용자/역할 관리도 가능한가요?
    → 네, LogtoM2MClient를 통해 사용자/역할 생성, 조회, 수정, 삭제, 할당 등 모든 관리가 가능합니다.

  • Q. Stateless 모드와 Stateful 모드의 차이는 무엇인가요?
    → Stateless 모드는 토큰 검증만 필요한 API 서버에 적합하며, 최소한의 환경변수(LOGTO_JWKS_URI, LOGTO_AUTH_ISSUER)만 필요합니다.
    → Stateful 모드는 LOGTO_CLIENT=true로 설정하여 로그인/로그아웃, M2M 통신 등 클라이언트 기능을 모두 사용할 수 있습니다.

  • Q. global 파라미터는 언제 사용하나요?
    forLogger의 세 번째 파라미터를 true로 설정하면 LogtoModule이 글로벌 모듈로 등록되어, 다른 모듈에서 별도의 import 없이 Logto 서비스들을 사용할 수 있습니다.

  • Q. 토큰 검증만 필요한데 모든 환경변수를 설정해야 하나요?
    → 아니요. 토큰 검증만 필요하다면 LOGTO_JWKS_URILOGTO_AUTH_ISSUER만 설정하면 됩니다. LOGTO_CLIENT를 설정하지 않거나 false로 설정하면 자동으로 Stateless 모드가 활성화됩니다.


🏷️ 내보내는 토큰/서비스

  • OAuthClientToken, LogtoM2MClientToken, LogtoTokenVerifierToken, LogtoLoginSessionToken, LogtoTokenGuard
  • 각 서비스/가드는 NestJS DI로 바로 주입받아 사용 가능

📚 참고


📝 라이선스

MIT