Go Fiber 한글 공식 문서
  • 🙇‍♀️안녕하세요
  • 🏠Home
    • 👋Welcome
    • 📁API
      • 📦Fiber
      • 🚀App
      • 🧠Ctx
      • 📋Constants
      • 🌎Client
      • 📃Log
      • 🧬Middleware
        • Adaptor
        • BasicAuth
        • Cache
        • Compress
        • CORS
        • CSRF
        • EarlyData
        • Encrypt Cookie
        • EnvVar
        • ETag
        • ExpVar
        • Favicon
        • FileSystem
        • Health Check
        • Helmet
        • Idempotency
        • Keyauth
        • Limiter
        • Logger
        • Monitor
        • Pprof
        • Proxy
        • Recover
        • Redirect
        • RequestID
        • Rewrite
        • Session
        • Skip
        • Timeout
    • 📁Guide
      • 🔌Routing
      • 🎭Grouping
      • 📝Templates
      • 🐛Error Handling
      • 🔎Validation
      • 🎣Hooks
      • ⚡Make Fiber Faster
    • 📁Extra
      • 🤔FAQ
      • 📊Benchmarks
  • 🧩Extra
    • 🧬Contrip
      • 👋Welcome
      • Casbin
      • Fgprof
      • Fiberi18n
      • Fibernewrelic
      • Fibersentry
      • Fiberzap
      • Fiberzerolog
      • JWT
      • LoadShed
      • Opafiber
      • Otelfiber
        • Example
      • Paseto
      • README
      • Swagger
      • Websocket
    • 📦Storage
      • 👋Welcome
      • ArangoDB
      • Azure Blob
      • Badger
      • Bbolt
      • Coherence
      • Couchbase
      • DynamoDB
      • Etcd
      • Memcache
      • Memory
      • Minio
      • MongoDB
      • MSSQL
      • MySQL
      • Nats
      • Pebble
      • Postgres
      • Redis
      • Ristretto
      • Rueidis
      • S3
      • ScyllaDb
      • SQLite3
    • 📃Template
      • 👋Welcome
      • Ace
      • Amber
      • Django
      • Handlebars
      • HTML
        • Golang Templates Cheatsheet
      • Jet
      • Mustache
      • Pug
      • Slim
Powered by GitBook
On this page
  • Installation
  • Signatures
  • Config
  • HS256 예제
  • HS256 테스트
  • RS256 예제
  • RS256 테스트
  • JWK 세트 테스트
  • 사용자 정의 KeyFunc 예제
  1. Extra
  2. Contrip

JWT

PreviousFiberzerologNextLoadShed

Last updated 1 year ago


JWT는 JSON Web Token(JWT) 인증 미들웨어를 반환합니다. 유효한 토큰의 경우 Ctx.Locals에 사용자를 설정하고 다음 핸들러를 호출합니다. 유효하지 않은 토큰의 경우 "401 - Unauthorized" 오류를 반환합니다. 토큰이 누락된 경우 "400 - Bad Request" 오류를 반환합니다.

에 특별한 감사와 크레딧을 드립니다.

참고: Go 1.19 이상 버전 필요

Installation

이 미들웨어는 Fiber v1 & v2를 지원하므로 그에 따라 설치하세요.

go get -u github.com/gofiber/fiber/v2
go get -u github.com/gofiber/contrib/jwt  
go get -u github.com/golang-jwt/jwt/v5

Signatures

jwtware.New(config ...jwtware.Config) func(*fiber.Ctx) error

Config

Property
Type
Description
Default

Filter

func(*fiber.Ctx) bool

미들웨어를 건너뛸 함수 정의

nil

SuccessHandler

func(*fiber.Ctx) error

유효한 토큰에 대해 실행되는 함수 정의

nil

ErrorHandler

func(*fiber.Ctx, error) error

유효하지 않은 토큰에 대해 실행되는 함수 정의

401 Invalid or expired JWT

SigningKey

interface{}

토큰 검증에 사용되는 서명 키. SigningKeys 길이가 0인 경우 대체 사용

nil

SigningKeys

map[string]interface{}

kid 필드 사용을 통해 토큰을 검증할 서명 키 맵

nil

ContextKey

string

토큰의 사용자 정보를 컨텍스트에 저장하는 컨텍스트 키

"user"

Claims

jwt.Claim

토큰 내용을 정의하는 확장 가능한 클레임 데이터

jwt.MapClaims{}

TokenLookup

string

<source>:<name> 형식의 문자열로 사용

"header:Authorization"

AuthScheme

string

Authorization 헤더에 사용할 인증 스킴. 기본값("Bearer")은 기본 TokenLookup 값과 함께 사용될 때만 사용

"Bearer"

KeyFunc

func() jwt.Keyfunc

토큰 검증을 위한 공개 키를 제공하는 사용자 정의 함수

jwtKeyFunc

JWKSetURLs

[]string

JWT를 파싱하는 데 사용되는 고유한 JSON Web Key(JWK) 세트 URL 슬라이스

nil

HS256 예제

package main

import (
    "time"
    
    "github.com/gofiber/fiber/v2"
    
    jwtware "github.com/gofiber/contrib/jwt"
    "github.com/golang-jwt/jwt/v5"
)

func main() {
    app := fiber.New()
    
    // 로그인 라우트
    app.Post("/login", login)
    
    // 인증되지 않은 라우트  
    app.Get("/", accessible)
    
    // JWT 미들웨어
    app.Use(jwtware.New(jwtware.Config{
        SigningKey: jwtware.SigningKey{Key: []byte("secret")},
    }))
    
    // 제한된 라우트
    app.Get("/restricted", restricted)
    
    app.Listen(":3000")
}

func login(c *fiber.Ctx) error {
    user := c.FormValue("user")
    pass := c.FormValue("pass")
    
    // 인증되지 않은 오류 발생
    if user != "john" || pass != "doe" {
        return c.SendStatus(fiber.StatusUnauthorized)  
    }
    
    // 클레임 생성
    claims := jwt.MapClaims{
        "name":  "John Doe",
        "admin": true,  
        "exp":   time.Now().Add(time.Hour * 72).Unix(),
    }
    
    // 토큰 생성
    token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
    
    // 인코딩된 토큰 생성 및 응답으로 전송
    t, err := token.SignedString([]byte("secret"))
    if err != nil {
        return c.SendStatus(fiber.StatusInternalServerError)
    }
    
    return c.JSON(fiber.Map{"token": t})
}

func accessible(c *fiber.Ctx) error {
    return c.SendString("Accessible")
}

func restricted(c *fiber.Ctx) error {
    user := c.Locals("user").(*jwt.Token)
    claims := user.Claims.(jwt.MapClaims)
    name := claims["name"].(string)
    return c.SendString("Welcome " + name)  
}

HS256 테스트

사용자 이름과 비밀번호를 사용하여 토큰을 검색하기 위해 로그인합니다.

curl --data "user=john&pass=doe" http://localhost:3000/login

응답

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0NjE5NTcxMzZ9.RB3arc4-OyzASAaUhC2W3ReWaXAt_z2Fd3BN4aWTgEY"
}

Authorization 요청 헤더의 토큰을 사용하여 제한된 리소스를 요청합니다.

curl localhost:3000/restricted -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0NjE5NTcxMzZ9.RB3arc4-OyzASAaUhC2W3ReWaXAt_z2Fd3BN4aWTgEY" 

응답

Welcome John Doe

RS256 예제

package main

import ( 
    "crypto/rand"
    "crypto/rsa"
    "log"  
    "time"
        
    "github.com/gofiber/fiber/v2"
        
    "github.com/golang-jwt/jwt/v5"
    
    jwtware "github.com/gofiber/contrib/jwt"
)

var (
    // 분명히 이는 단순한 테스트 예제일 뿐입니다. 프로덕션에서는 이렇게 하지 마세요.
    // 프로덕션에서는 사전에 생성된 비공개 키와 공개 키 쌍을 가지고 있어야 합니다.
    // 절대 GitHub 저장소에 비공개 키를 추가하지 마세요.
    privateKey *rsa.PrivateKey  
)

func main() {
    app := fiber.New()
    
    // 데모용으로만 각 실행마다 새 개인 키/공개 키 쌍을 생성합니다. 위 주석을 참조하세요.
    rng := rand.Reader
    var err error
    privateKey, err = rsa.GenerateKey(rng, 2048) 
    if err != nil {
        log.Fatalf("rsa.GenerateKey: %v", err)
    }
    
    // 로그인 라우트
    app.Post("/login", login)
    
    // 인증되지 않은 라우트
    app.Get("/", accessible)
    
    // JWT 미들웨어  
    app.Use(jwtware.New(jwtware.Config{
        SigningKey: jwtware.SigningKey{
            JWTAlg: jwtware.RS256,
            Key:    privateKey.Public(), 
        },
    }))
    
    // 제한된 라우트
    app.Get("/restricted", restricted)
    
    app.Listen(":3000")
}

func login(c *fiber.Ctx) error {
    user := c.FormValue("user")
    pass := c.FormValue("pass")
    
    // 인증되지 않은 오류 발생
    if user != "john" || pass != "doe" {
        return c.SendStatus(fiber.StatusUnauthorized)
    }
    
    // 클레임 생성
    claims := jwt.MapClaims{
        "name":  "John Doe", 
        "admin": true,
        "exp":   time.Now().Add(time.Hour * 72).Unix(),
    }
    
    // 토큰 생성
    token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
    
    // 인코딩된 토큰 생성 및 응답으로 전송
    t, err := token.SignedString(privateKey)
    if err != nil {
        log.Printf("token.SignedString: %v", err)
        return c.SendStatus(fiber.StatusInternalServerError)
    }
    
    return c.JSON(fiber.Map{"token": t})
}

func accessible(c *fiber.Ctx) error {
    return c.SendString("Accessible")  
}

func restricted(c *fiber.Ctx) error {
    user := c.Locals("user").(*jwt.Token)
    claims := user.Claims.(jwt.MapClaims)
    name := claims["name"].(string)
    return c.SendString("Welcome " + name)
}

RS256 테스트

RS256은 실제로 위의 HS256 테스트와 동일합니다.

JWK 세트 테스트

사용자 정의 KeyFunc 예제

KeyFunc는 토큰 검증을 위한 공개 키를 제공하는 사용자 정의 함수를 정의합니다. 이 함수는 서명 알고리즘을 검증하고 적절한 키를 선택하는 작업을 수행해야 합니다. 사용자 정의 KeyFunc는 토큰이 외부 당사자에 의해 발행된 경우 유용할 수 있습니다.

사용자 정의 KeyFunc가 제공되면 SigningKey, SigningKeys 및 SigningMethod는 무시됩니다. 이는 토큰 검증 키를 제공하는 세 가지 옵션 중 하나입니다. 우선 순위는 사용자 정의 KeyFunc, SigningKeys 및 SigningKey 순입니다. SigningKeys와 SigningKey가 모두 제공되지 않은 경우 필요합니다. 서명 알고리즘을 검증하고 적절한 키를 선택하는 내부 구현으로 기본 설정됩니다.

package main

import (
    "fmt"
  "github.com/gofiber/fiber/v2"
    
  jwtware "github.com/gofiber/contrib/jwt" 
  "github.com/golang-jwt/jwt/v5"
)

func main() {
    app := fiber.New()
    
    app.Use(jwtware.New(jwtware.Config{
        KeyFunc: customKeyFunc(),
    }))
    
    app.Get("/ok", func(c *fiber.Ctx) error {
        return c.SendString("OK")
    })
}

func customKeyFunc() jwt.Keyfunc {
    return func(t *jwt.Token) (interface{}, error) {
        // 항상 서명 방법을 확인하세요
        if t.Method.Alg() != jwtware.HS256 {
            return nil, fmt.Errorf("Unexpected jwt signing method=%v", t.Header["alg"])  
        }
        
        // TODO 데이터베이스 등에서 서명 키를 로드하는 사용자 정의 구현
    signingKey := "secret"
        
        return []byte(signingKey), nil
    }
}

테스트는 위의 기본 JWT 테스트와 동일하지만, 에 명시된 JSON Web Key(JWK) 세트 형식의 유효한 공개 키 컬렉션에 대한 JWKSetURLs를 제공해야 한다는 점이 다릅니다.

🧩
🧬
RFC 7517
Echo