[go] Go 언어를 사용한 RESTful API의 인증 및 권한 부여 방식

Go 언어는 간결하고 효율적인 웹 애플리케이션 개발을 지원하는 인기있는 프로그래밍 언어입니다. 이번 블로그 포스트에서는 Go 언어를 사용하여 RESTful API의 인증과 권한 부여를 구현하는 방법에 대해 알아보겠습니다.

인증(Authentication)과 권한 부여(Authorization)의 개념

인증은 사용자가 자신이 주장하는 신원을 입증하는 과정을 의미합니다. API 사용자가 자신의 신원을 인증해야만 해당 API의 보호된 리소스에 접근할 수 있습니다. 인증 방법에는 다양한 형태가 있지만, 가장 일반적인 방법은 사용자의 아이디와 패스워드를 사용하는 기본 인증 방식입니다.

반면에 권한 부여는 인증된 사용자가 특정 리소스에 접근할 권한이 있는지 여부를 결정하는 과정입니다. 예를 들어, 관리자 권한이 있는 사용자만 특정 API 엔드포인트를 호출할 수 있다면, 해당 사용자의 권한 부여가 필요합니다.

JWT(JSON Web Token)를 사용한 인증

JWT는 인증을 위한 자체적인 토큰 기반 프로토콜로 널리 사용되고 있습니다. Go 언어에서 JWT를 사용하여 인증할 수 있습니다.

package main

import (
	"fmt"
	"net/http"

	"github.com/dgrijalva/jwt-go"
)

var secretKey = []byte("your_secret_key")

func generateToken() (string, error) {
	claims := jwt.MapClaims{
		"username": "john.doe",
	}

	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	signedToken, err := token.SignedString(secretKey)
	if err != nil {
		return "", err
	}

	return signedToken, nil
}

func authenticate(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		tokenString := extractTokenFromHeader(r)
		token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
			if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
				return nil, fmt.Errorf("unexpected signing method")
			}

			return secretKey, nil
		})

		if err != nil {
			w.WriteHeader(http.StatusUnauthorized)
			return
		}

		if !token.Valid {
			w.WriteHeader(http.StatusUnauthorized)
			return
		}

		next(w, r)
	}
}

func extractTokenFromHeader(r *http.Request) string {
	token := r.Header.Get("Authorization")
	// 예를 들어, "Bearer {token}" 형태로 전달된다고 가정합니다.
	// "Bearer " 부분을 제외하고 토큰 문자열만 추출합니다.
	return token[len("Bearer "):]
}

func main() {
	http.HandleFunc("/protected", authenticate(func(w http.ResponseWriter, r *http.Request) {
		// 권한 부여 로직을 추가합니다.
		w.WriteHeader(http.StatusOK)
		w.Write([]byte("Access granted to protected resource"))
	}))

	http.ListenAndServe(":8080", nil)
}

위의 코드에서 generateToken() 함수는 사용자의 신원을 기반으로 JWT 토큰을 생성합니다. authenticate() 함수는 인증 미들웨어로, 각 API 엔드포인트에 적용됩니다. 헤더에서 토큰을 추출한 다음, 추출된 토큰을 검증하여 인증 여부를 판단합니다.

권한 부여

API의 보호된 리소스에 접근하기 위해서는 권한 부여 기능이 필요합니다.

func authorize(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		// 현재 사용자의 권한을 확인하고 필요한 권한이 있는지 검사합니다.
		// 필요한 권한이 없다면 403 Forbidden 상태코드를 반환합니다.
		// 필요한 권한이 있다면 next(w, r)를 호출하여 다음 핸들러로 넘깁니다.
	}
}

위의 코드에서 authorize() 함수는 권한 부여 미들웨어로, 각 API 엔드포인트에 추가됩니다. 현재 사용자의 권한을 확인하고 필요한 권한이 있는지 여부를 판단한 후, 필요한 권한이 없는 경우 403 Forbidden 상태 코드를 반환합니다.

결론

Go 언어를 사용하여 RESTful API의 인증과 권한 부여를 구현하는 방법에 대해 알아보았습니다. 효율적이고 보안성이 높은 JWT를 사용하여 인증을 처리하고, 권한 부여를 구현하기 위해 권한 부여 미들웨어를 추가할 수 있습니다. 이러한 구현은 API의 보안과 접근 제어를 유연하게 관리할 수 있게 도와줍니다.