Go의 Auth0 JWT 미들웨어 - Gin 웹 프레임워크
Auth0 Golang JWT 미들웨어 안정 버전 v2.0.0 2022년 1월 19일 출시
Release v2.0.0 · auth0/go-jwt-middleware
진 웹 프레임워크
Gin은 웹 애플리케이션과 마이크로서비스를 구축할 수 있는 고성능 마이크로 프레임워크입니다. 재사용 가능한 모듈식 조각에서 요청 처리 파이프라인을 간단하게 구축할 수 있습니다. 하나 이상의 요청 처리기 또는 요청 처리기 그룹에 연결할 수 있는 미들웨어를 작성할 수 있도록 하여 이를 수행합니다.
Golang Gin Web Framework를 사용하여 간단한 API를 만들어 봅시다.
go get -u github.com/gin-gonic/gin
package main
import (
"context"
"net/http"
"github.com/gin-gonic/gin"
)
type Product struct {
ID int `json:"id"`
Title string `json:"title"`
Code string `json:"code"`
Price float32 `json:"price"`
}
func main() {
r := gin.Default()
r.GET("/products", func(c *gin.Context) {
products := []Product{
{ID: 1, Title: "Product 1", Code: "p1", Price: 100.0},
{ID: 2, Title: "Product 2", Code: "p2", Price: 200.0},
{ID: 3, Title: "Product 3", Code: "p3", Price: 300.0},
}
c.JSON(http.StatusOK, products)
})
// Listen and Server in 0.0.0.0:5000
r.Run(":5000")
}
JWT 미들웨어 추가
Auth0 API를 구성하기 전에 Auth0 Golang JWT 미들웨어를 통합합시다.
GitHub - auth0/go-jwt-middleware: A Middleware for Go Programming Language to check for JWTs on HTTP requests
go get github.com/auth0/go-jwt-middleware/v2
Auth0 Golang JWT 미들웨어는 HTTP 미들웨어 핸들러입니다. Gin 웹 프레임워크에서 사용하려면 일반 HTTP 미들웨어를 Gin 미들웨어 처리기로 래핑하는 래퍼가 필요합니다. 이를 위해 Gareth Watts의 Gin Adapter를 사용하고 있습니다. https://github.com/gwatts/gin-adapter
package main
import (
"context"
"net/http"
jwtmiddleware "github.com/auth0/go-jwt-middleware/v2"
"github.com/auth0/go-jwt-middleware/v2/validator"
"github.com/gin-gonic/gin"
"github.com/gwatts/gin-adapter"
)
type Product struct {
ID int `json:"id"`
Title string `json:"title"`
Code string `json:"code"`
Price float32 `json:"price"`
}
func main() {
r := gin.Default()
keyFunc := func(ctx context.Context) (interface{}, error) {
return []byte("secret"), nil
}
jwtValidator, _ := validator.New(keyFunc, validator.HS256, "http://localhost:5000", []string{"api:read"})
jwtMiddleware := jwtmiddleware.New(jwtValidator.ValidateToken)
// Wrap the http handler with gin adapter
r.Use(adapter.Wrap(jwtMiddleware.CheckJWT))
r.GET("/products", func(c *gin.Context) {
products := []Product{
{ID: 1, Title: "Product 1", Code: "p1", Price: 100.0},
{ID: 2, Title: "Product 2", Code: "p2", Price: 200.0},
{ID: 3, Title: "Product 3", Code: "p3", Price: 300.0},
}
c.JSON(http.StatusOK, products)
})
// Listen and Server in 0.0.0.0:5000
r.Run(":5000")
}
JWT URL을 사용하여 이 API를 테스트해 보겠습니다.
curl --location --request GET 'http://localhost:5000/products' \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjUwMDAiLCJhdWQiOiJhcGk6cmVhZCJ9.hbgwKW_RILeXXDDUv5bVK3WgjtvqoK5IiuisgnFWefY'
공유 비밀
[http://localhost:5000](http://localhost:5000)
이 있는 HS256 알고리즘을 사용하여 발급자api:read
및 대상secret
이 있는 새 JWT를 생성할 수 있습니다.➜ ~ curl --location --request GET 'http://localhost:5000/products' \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjUwMDAiLCJhdWQiOiJhcGk6cmVhZCJ9.hbgwKW_RILeXXDDUv5bVK3WgjtvqoK5IiuisgnFWefY' | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 160 100 160 0 0 6011 0 --:--:-- --:--:-- --:--:-- 20000
[
{
"id": 1,
"title": "Product 1",
"code": "p1",
"price": 100
},
{
"id": 2,
"title": "Product 2",
"code": "p2",
"price": 200
},
{
"id": 3,
"title": "Product 3",
"code": "p3",
"price": 300
}
]
Auth0 API 구성
이제 Auth0을 사용하여 API에 권한 부여를 추가할 차례입니다. 서명 알고리즘 RS256으로 Auth0 API를 구성하고 RS256을 지원하도록 Auth0 Golang 미들웨어 코드를 변경해 보겠습니다.
API에서 권한
read:products
추가RS256 서명 JWT 토큰의 유효성을 검사하도록 Auth0 미들웨어를 변경합니다.
issuerURL, _ := url.Parse(os.Getenv("AUTH0_ISSUER_URL"))
audience := os.Getenv("AUTH0_AUDIENCE")
provider := jwks.NewCachingProvider(issuerURL, time.Duration(5*time.Minute))
jwtValidator, _ := validator.New(provider.KeyFunc,
validator.RS256,
issuerURL.String(),
[]string{audience},
)
jwtMiddleware := jwtmiddleware.New(jwtValidator.ValidateToken)
r.Use(adapter.Wrap(jwtMiddleware.CheckJWT))
전체 코드는 아래와 같습니다.
package main
import (
"log"
"net/http"
"net/url"
"os"
"time"
adapter "github.com/gwatts/gin-adapter"
jwtmiddleware "github.com/auth0/go-jwt-middleware/v2"
"github.com/auth0/go-jwt-middleware/v2/jwks"
"github.com/auth0/go-jwt-middleware/v2/validator"
"github.com/gin-gonic/gin"
"github.com/joho/godotenv"
)
type Product struct {
ID int `json:"id"`
Title string `json:"title"`
Code string `json:"code"`
Price float32 `json:"price"`
}
func main() {
err := godotenv.Load()
if err != nil {
log.Fatal("Error loading .env file")
}
r := gin.Default()
issuerURL, _ := url.Parse(os.Getenv("AUTH0_ISSUER_URL"))
audience := os.Getenv("AUTH0_AUDIENCE")
provider := jwks.NewCachingProvider(issuerURL, time.Duration(5*time.Minute))
jwtValidator, _ := validator.New(provider.KeyFunc,
validator.RS256,
issuerURL.String(),
[]string{audience},
)
jwtMiddleware := jwtmiddleware.New(jwtValidator.ValidateToken)
r.Use(adapter.Wrap(jwtMiddleware.CheckJWT))
r.GET("/products", func(c *gin.Context) {
products := []Product{
{ID: 1, Title: "Product 1", Code: "p1", Price: 100.0},
{ID: 2, Title: "Product 2", Code: "p2", Price: 200.0},
{ID: 3, Title: "Product 3", Code: "p3", Price: 300.0},
}
c.JSON(http.StatusOK, products)
})
// Listen and Server in 0.0.0.0:5000
r.Run(":5000")
}
Auth0 JWT 확인
API 테스트 페이지에서 테스트 JWT를 만듭니다. 테스트 토큰으로 API를 호출합니다.
➜ auth0-go-gin-middleware curl --location --request GET 'http://localhost:5000/products' \
--header 'authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6InVUT0ktNGhrSDBWNU9YUGxKV0xpXyJ9.eyJpc3MiOiJodHRwczovL3NpdmEtZGVtby1hcHAudXMuYXV0aDAuY29tLyIsInN1YiI6Inl2N1NDekVueUxTWGdMZ1d3b2pJODZvNk5ZMzh0cmNtQGNsaWVudHMiLCJhdWQiOiJodHRwczovL3Byb2R1Y3RzLWFwaS8iLCJpYXQiOjE2NDM0MzM4NTYsImV4cCI6MTY0MzUyMDI1NiwiYXpwIjoieXY3U0N6RW55TFNYZ0xnV3dvakk4Nm82TlkzOHRyY20iLCJndHkiOiJjbGllbnQtY3JlZGVudGlhbHMifQ.yH13H5XxLEABu3o8s2HZUs8Q9PXHeLGUcELQdlrYoClKP3k3B_WdUpaH2_c-UpA1ZjB_Is71-hSt3iqQN_OaMV_fFqpnt0qJQNXsoWSHBE5CzDDAclRlFf5XaWVbcA072rzUAtrJuPzHYf8kdR91243lJFA_13V5vlQuWxqFxas4FonVR5OLGcXYHqLfBI76DPfFaOBwOzefSYSI_jxKrrQtnux4Ktkqrgo7tpFckY6UfD6fXPeRvk4xLSb_SteAwcpCQrWJVyt7gTWv4_KkSNEyZduEbMTrnkU_jdQjHuKOLaTBc4t7t3MK_2_tmrda5xn0QXf-1y6P2M4zQu2mWA' | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 160 100 160 0 0 8045 0 --:--:-- --:--:-- --:--:-- 40000
[
{
"id": 1,
"title": "Product 1",
"code": "p1",
"price": 100
},
{
"id": 2,
"title": "Product 2",
"code": "p2",
"price": 200
},
{
"id": 3,
"title": "Product 3",
"code": "p3",
"price": 300
}
]
결론
이 블로그 게시물에서는 Auth0 Golang 미들웨어 v2.0.0을 사용하여 HS256 및 RS256 서명 모두에서 JWT를 확인하는 방법을 살펴보았습니다. 이 데모 프로젝트를 확장하여 JWT 등에서 사용자 지정 클레임을 확인할 수 있습니다. 다음 블로그 게시물에서 더 자세히 살펴보겠습니다.
Reference
이 문제에 관하여(Go의 Auth0 JWT 미들웨어 - Gin 웹 프레임워크), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/ksivamuthu/auth0-jwt-middleware-in-go-gin-web-framework-37mj텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)