커스텀 Claims
내장 Claims 구조체는 일반적인 시나리오를 다루지만, 비즈니스 시스템은 일반적으로 추가 필드가 필요합니다. CustomClaims 인터페이스를 구현하여 자체 Claims 구조체를 정의할 수 있습니다.
CustomClaims 인터페이스
go
type CustomClaims interface {
GetRegisteredClaims() *RegisteredClaims
Validate() error
}두 가지 메서드만 구현하면 됩니다:
| 메서드 | 설명 |
|---|---|
GetRegisteredClaims() | 표준 JWT 필드 반환 (iss, sub, aud 등) |
Validate() | 커스텀 검증 로직 |
커스텀 Claims 정의
go
type MyClaims struct {
UserID string `json:"user_id"`
Email string `json:"email"`
Role string `json:"role"`
jwt.RegisteredClaims
}
func (c *MyClaims) GetRegisteredClaims() *jwt.RegisteredClaims {
return &c.RegisteredClaims
}
func (c *MyClaims) Validate() error {
if c.UserID == "" {
return errors.New("user_id is required")
}
if c.Email == "" {
return errors.New("email is required")
}
return nil
}핵심 포인트
jwt.RegisteredClaims를 반드시 임베드해야 합니다GetRegisteredClaims()는 임베드된 필드의 포인터를 반환해야 합니다Validate()는 토큰 생성과 검증 시 모두 호출됩니다
커스텀 Claims 사용
토큰 생성
go
claims := &MyClaims{
UserID: "user123",
Email: "[email protected]",
Role: "admin",
}
token, err := processor.Create(claims)커스텀 구조체로 검증
ValidateInto를 사용하여 토큰을 커스텀 구조체로 파싱:
go
myClaims := &MyClaims{}
result, valid, err := processor.ValidateInto(token, myClaims)
if err != nil {
panic(err)
}
if valid {
parsed := result.(*MyClaims)
fmt.Println("UserID:", parsed.UserID)
fmt.Println("Email:", parsed.Email)
}커스텀 구조체로 갱신
RefreshInto를 사용하여 토큰을 갱신하고 커스텀 필드를 유지:
go
newToken, err := processor.RefreshInto(refreshToken, &MyClaims{})
if err != nil {
panic(err)
}시간 필드 보호
RefreshInto는 Claims 의 시간 필드 (IssuedAt, ExpiresAt, ID) 를 자동으로 복원하며, 작업이 실패해도 복원이 보장됩니다.
검증 차이
내장 *Claims와 커스텀 타입은 서로 다른 검증 경로를 따릅니다:
| 검증 항목 | *Claims | 커스텀 타입 |
|---|---|---|
Validate() 메서드 | ✅ | ✅ |
| 문자열 길이 제한 (256 자) | ✅ | ❌ |
| 배열 크기 제한 (100 개 항목) | ✅ | ❌ |
| 인젝션 패턴 감지 | ✅ | ❌ |
| 제어 문자 필터링 | ✅ | ❌ |
Extra 필드 제한 | ✅ | 해당 없음 |
| 등록 선언 문자열 정제 | ✅ | ✅ |
중요
커스텀 Claims 의 비즈니스 필드는 심층 검증되지 않습니다. Validate() 메서드에서 필요한 모든 검증을 직접 구현하세요.
선택적 인터페이스: RateLimitKeyer
커스텀 Claims 는 RateLimitKeyer 인터페이스를 구현하여 속도 제한 키를 제공할 수 있습니다:
go
func (c *MyClaims) RateLimitKey() string {
return c.Email // Email 을 속도 제한 키로 사용
}속도 제한 키 조회 우선순위: Subject → *Claims.UserID → RateLimitKey().
다음 단계
- API 레퍼런스 → 인터페이스 정의 — CustomClaims 전체 정의
- API 레퍼런스 → Processor — ValidateInto / RefreshInto 메서드
- 고급 예제 — 커스텀 Claims 전체 예제