> ## Documentation Index
> Fetch the complete documentation index at: https://sonamu.cartanova.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# AuthContext

> Sonamu 인증 컨텍스트 레퍼런스

AuthContext는 Context의 일부로, 사용자 인증 상태와 세션 정보를 제공합니다. [better-auth](https://www.better-auth.com/)를 기반으로 구현되어 있습니다.

## 타입 정의

```typescript theme={null}
import type { Session, User } from "better-auth";

type AuthContext = {
  /** 현재 로그인한 사용자 (null이면 미인증) */
  user: User | null;
  /** 현재 세션 정보 (null이면 미인증) */
  session: Session | null;
};
```

## 속성

### user

```typescript theme={null}
user: User | null;
```

현재 인증된 사용자 정보입니다. 로그인하지 않은 경우 `null`입니다.

`User` 타입은 better-auth에서 제공하며, 기본적으로 다음 필드를 포함합니다:

```typescript theme={null}
type User = {
  id: string;
  name: string;
  email: string;
  emailVerified: boolean;
  image: string | null;
  createdAt: Date;
  updatedAt: Date;
};
```

**사용 예시:**

```typescript theme={null}
import { Sonamu } from "sonamu";

class UserModelClass extends BaseModelClass {
  @api({ httpMethod: "GET", guards: ["user"] })
  async getMyProfile() {
    const { user } = Sonamu.getContext();

    if (!user) {
      throw new UnauthorizedException("로그인이 필요합니다");
    }

    return {
      id: user.id,
      email: user.email,
      name: user.name,
    };
  }
}
```

### session

```typescript theme={null}
session: Session | null;
```

현재 세션 정보입니다. 로그인하지 않은 경우 `null`입니다.

`Session` 타입은 better-auth에서 제공하며, 다음 필드를 포함합니다:

```typescript theme={null}
type Session = {
  id: string;
  userId: string;
  token: string;
  expiresAt: Date;
  createdAt: Date;
  updatedAt: Date;
};
```

**사용 예시:**

```typescript theme={null}
class SessionModelClass extends BaseModelClass {
  @api({ httpMethod: "GET", guards: ["user"] })
  async getSessionInfo() {
    const { session } = Sonamu.getContext();

    return {
      sessionId: session.id,
      expiresAt: session.expiresAt,
    };
  }
}
```

## 설정

AuthContext를 사용하려면 `sonamu.config.ts`에서 인증 설정을 해야 합니다.

### 기본 설정

```typescript theme={null}
// sonamu.config.ts
import type { SonamuConfig } from "sonamu";

export default {
  server: {
    auth: {
      emailAndPassword: { enabled: true },
    },
  },
} satisfies SonamuConfig;
```

### 소셜 로그인 추가

```typescript theme={null}
// sonamu.config.ts
export default {
  server: {
    auth: {
      emailAndPassword: { enabled: true },
      socialProviders: {
        google: {
          clientId: process.env.GOOGLE_CLIENT_ID!,
          clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
        },
      },
    },
  },
} satisfies SonamuConfig;
```

## Guards를 통한 접근 제어

API 메서드에 인증을 요구하려면 `guards` 옵션을 사용할 수 있습니다:

```typescript theme={null}
class UserModelClass extends BaseModelClass {
  @api({ httpMethod: "GET", guards: ["user"] })
  async getMyData() {
    const { user } = Sonamu.getContext();
    // guards: ["user"]로 인해 user가 null이 아님이 보장됨
    return this.findById("A", user!.id);
  }

  @api({ httpMethod: "GET", guards: ["admin"] })
  async getAllUsers() {
    // guards: ["admin"]으로 관리자만 접근 가능
    return this.findMany("A", {});
  }
}
```

Guard 처리 로직은 `guardHandler`에서 구현합니다:

```typescript theme={null}
// sonamu.config.ts
import { Sonamu } from "sonamu";

export default {
  server: {
    apiConfig: {
      guardHandler: (guard, request, api) => {
        const { user } = Sonamu.getContext();

        if (guard === "user" && !user) {
          throw new UnauthorizedException("로그인이 필요합니다");
        }

        if (guard === "admin") {
          if (!user || (user as any).role !== "admin") {
            throw new UnauthorizedException("관리자 권한이 필요합니다");
          }
        }

        return true;
      },
    },
  },
} satisfies SonamuConfig;
```

<Info>
  `guardHandler`는 AsyncLocalStorage 내부에서 실행되므로 `Sonamu.getContext()`를 통해 현재 요청의
  Context에 접근할 수 있습니다.
</Info>

## User 타입 확장

프로젝트에서 User 엔티티에 필드를 추가한 경우, Sonamu UI를 통해 엔티티를 수정하면 됩니다. 추가한 필드는 `user` 객체에서 접근할 수 있지만, TypeScript 타입 안전성을 위해 타입 단언이 필요합니다:

```typescript theme={null}
const { user } = Sonamu.getContext();

// role 필드를 추가한 경우
const userRole = (user as any).role;

// 또는 타입 가드 사용
interface ExtendedUser extends User {
  role: "admin" | "user" | "manager";
}

function isExtendedUser(user: User | null): user is ExtendedUser {
  return user !== null && "role" in user;
}

if (isExtendedUser(user)) {
  console.log(user.role); // 타입 안전
}
```

## 인증 흐름

1. 클라이언트가 `/api/auth/sign-in/email`로 로그인 요청
2. better-auth가 인증 처리 및 세션 생성
3. 세션 토큰이 쿠키에 저장됨
4. 이후 요청에서 쿠키의 토큰으로 사용자 식별
5. API 메서드 실행 전 Context에 user/session 주입
6. `Sonamu.getContext()`로 사용자 정보 접근

## 관련 문서

* [Context](/ko/api-reference/context/sonamu-context)
* [인증 설정하기](/ko/api-development/authentication/setup)
* [Guards 사용하기](/ko/api-development/guards)
