Keyauth


Keyauth 미들웨어는 키 기반 인증을 제공합니다.

Signatures

func New(config ...Config) fiber.Handler

Examples

package main

import (
	"crypto/sha256"
	"crypto/subtle"
	"github.com/gofiber/fiber/v2"
	"github.com/gofiber/fiber/v2/middleware/keyauth"
)

var (
	apiKey = "correct horse battery staple"
)

func validateAPIKey(c *fiber.Ctx, key string) (bool, error) {
	hashedAPIKey := sha256.Sum256([]byte(apiKey))
	hashedKey := sha256.Sum256([]byte(key))

	if subtle.ConstantTimeCompare(hashedAPIKey[:], hashedKey[:]) == 1 {
		return true, nil
	}
	return false, keyauth.ErrMissingOrMalformedAPIKey
}

func main() {
	app := fiber.New()

	// keyauth 미들웨어는 라우트가 정의되기 전에 정의되어야 합니다!
	app.Use(keyauth.New(keyauth.Config{
		KeyLookup:  "cookie:access_token",
		Validator:  validateAPIKey,
	}))

	app.Get("/", func(c *fiber.Ctx) error {
		return c.SendString("성공적으로 인증되었습니다!")
	})

	app.Listen(":3000")
}

테스트:

# api-key가 지정되지 않음 -> 400 missing 
curl http://localhost:3000
#> missing or malformed API Key

curl --cookie "access_token=correct horse battery staple" http://localhost:3000
#> 성공적으로 인증되었습니다!

curl --cookie "access_token=Clearly A Wrong Key" http://localhost:3000
#>  missing or malformed API Key

보다 자세한 예시는 github.com/gofiber/recipes 저장소와 특히 fiber-envoy-extauthz 저장소 및 keyauth example 코드를 참조하십시오.

특정 엔드포인트만 인증하기

특정 엔드포인트만 인증하려면 keyauth의 Config를 사용하고 다음과 같이 필터 함수(예: authFilter)를 적용할 수 있습니다.

package main

import (
	"crypto/sha256"
	"crypto/subtle"
	"github.com/gofiber/fiber/v2"
	"github.com/gofiber/fiber/v2/middleware/keyauth"
	"regexp"
	"strings"
)

var (
	apiKey        = "correct horse battery staple"
	protectedURLs = []*regexp.Regexp{
		regexp.MustCompile("^/authenticated$"),
		regexp.MustCompile("^/auth2$"),
	}
)

func validateAPIKey(c *fiber.Ctx, key string) (bool, error) {
	hashedAPIKey := sha256.Sum256([]byte(apiKey))
	hashedKey := sha256.Sum256([]byte(key))

	if subtle.ConstantTimeCompare(hashedAPIKey[:], hashedKey[:]) == 1 {
		return true, nil
	}
	return false, keyauth.ErrMissingOrMalformedAPIKey
}

func authFilter(c *fiber.Ctx) bool {
	originalURL := strings.ToLower(c.OriginalURL())

	for _, pattern := range protectedURLs {
		if pattern.MatchString(originalURL) {
			return false
		}
	}
	return true
}

func main() {
	app := fiber.New()

	app.Use(keyauth.New(keyauth.Config{
		Next:    authFilter,
		KeyLookup: "cookie:access_token",
		Validator: validateAPIKey,
	}))

	app.Get("/", func(c *fiber.Ctx) error {
		return c.SendString("환영합니다")
	})
	app.Get("/authenticated", func(c *fiber.Ctx) error {
		return c.SendString("성공적으로 인증되었습니다!")
	})
	app.Get("/auth2", func(c *fiber.Ctx) error {
		return c.SendString("성공적으로 인증되었습니다 2!")
	})

	app.Listen(":3000")
}

다음과 같은 결과가 나옵니다.

# /은 인증이 필요하지 않습니다
curl http://localhost:3000
#> 환영합니다

# /authenticated는 인증이 필요합니다
curl --cookie "access_token=correct horse battery staple" http://localhost:3000/authenticated  
#> 성공적으로 인증되었습니다!

# /auth2도 인증이 필요합니다
curl --cookie "access_token=correct horse battery staple" http://localhost:3000/auth2
#> 성공적으로 인증되었습니다 2!

핸들러에서 미들웨어 지정하기

package main

import (
	"crypto/sha256"
	"crypto/subtle"
	"github.com/gofiber/fiber/v2"
	"github.com/gofiber/fiber/v2/middleware/keyauth"
)

const (
  apiKey = "my-super-secret-key"
)

func main() {
	app := fiber.New()

	authMiddleware := keyauth.New(keyauth.Config{
		Validator:  func(c *fiber.Ctx, key string) (bool, error) {
			hashedAPIKey := sha256.Sum256([]byte(apiKey))
			hashedKey := sha256.Sum256([]byte(key))

			if subtle.ConstantTimeCompare(hashedAPIKey[:], hashedKey[:]) == 1 {
				return true, nil
			}
			return false, keyauth.ErrMissingOrMalformedAPIKey
		},
	})

	app.Get("/", func(c *fiber.Ctx) error {
		return c.SendString("환영합니다")
	})

	app.Get("/allowed",  authMiddleware, func(c *fiber.Ctx) error {
		return c.SendString("성공적으로 인증되었습니다!")
	})

	app.Listen(":3000")
}

다음과 같은 결과가 나옵니다.

# / 는 인증이 필요하지 않습니다
curl http://localhost:3000
#> 환영합니다

# /allowed 는 인증이 필요합니다
curl --header "Authorization: Bearer my-super-secret-key"  http://localhost:3000/allowed
#> 성공적으로 인증되었습니다!

Config

속성
타입
설명
기본값

Next

func(*fiber.Ctx) bool

Next는 true를 반환할 때 이 미들웨어를 건너뛰는 함수를 정의합니다.

nil

SuccessHandler

fiber.Handler

SuccessHandler는 유효한 키에 대해 실행되는 함수를 정의합니다.

nil

ErrorHandler

fiber.ErrorHandler

ErrorHandler는 유효하지 않은 키에 대해 실행되는 함수를 정의합니다.

401 Invalid or expired key

KeyLookup

string

KeyLookup은 "<source>:<name>" 형식의 문자열로, 요청에서 키를 추출하는 데 사용됩니다.

"header:Authorization"

AuthScheme

string

Authorization 헤더에 사용될 AuthScheme입니다.

"Bearer"

Validator

func(*fiber.Ctx, string) (bool, error)

Validator는 키를 검증하는 함수입니다.

키 검증을 위한 함수

ContextKey

interface{}

토큰의 bearer 토큰을 컨텍스트에 저장하기 위한 컨텍스트 키입니다.

"token"

Default Config

var ConfigDefault = Config{
	SuccessHandler: func(c *fiber.Ctx) error {
		return c.Next()
	},
	ErrorHandler: func(c *fiber.Ctx, err error) error {
		if err == ErrMissingOrMalformedAPIKey {
			return c.Status(fiber.StatusUnauthorized).SendString(err.Error())
		}
		return c.Status(fiber.StatusUnauthorized).SendString("Invalid or expired API Key")
	},
	KeyLookup:  "header:" + fiber.HeaderAuthorization,
	AuthScheme: "Bearer", 
	ContextKey: "token",
}

Last updated