Fiber JWT
JWT middleware, JSON Web Token (JWT) kimlik doğrulama ara yazılımını döndürür. Geçerli bir jeton için kullanıcıyı Ctx.Locals'e ayarlar ve sonraki işleyiciyi çağırır. Geçersiz bir jeton için "401 - Yetkisiz" hatası döndürür. Eksik bir jeton için "400 - Kötü İstek" hatası döndürür.
Not: Go sürüm 1.19 veya daha yükseği gerektirir
Kurulum
Bu ara yazılım, Fiber v1 ve v2'yi destekler, lütfen buna göre yükleyin.
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
İmza
jwtware.New(config ...jwtware.Config) func(*fiber.Ctx) error
Yapılandırma
Özellik | Tür | Açıklama | Varsayılan Değer |
---|---|---|---|
Filtre | func(*fiber.Ctx) bool |
Ara yazılımı atlamak için bir işlev tanımlar | nil |
Başarı İşleyici | func(*fiber.Ctx) error |
Geçerli jetonla uygun işlevi tanımlar | nil |
Hata İşleyici | func(*fiber.Ctx, error) error |
Geçersiz jetonla uygun işlevi tanımlar | 401 Geçersiz veya süresi dolmuş JWT |
İmza Anahtarı | interface{} |
Jetonu doğrulamak için kullanılan imza anahtarı. SigningKeys'in uzunluğu 0 ise yedek olarak kullanılır | nil |
İmza Anahtarları | map[string]interface{} |
kid alanıyla jetonları doğrulamak için kullanılan imza anahtarlarının eşlemesi |
nil |
Context Anahtarı | string |
Kullanıcı bilgisini içerikteki çalışma alanına depolamak için kullanılan bağlam anahtarı | "kullanıcı" |
Talepler | jwt.Claim |
Jeton içeriğini tanımlayan genişletilmiş talepler veri yapısı | jwt.MapClaims{} |
Token Arayışı | string |
: biçiminde kullanılan jetonu ayrıştırmak için bir dize |
"header:Authorization" |
AuthScheme | string |
Yetki başlığında kullanılan AuthScheme. Varsayılan değer ("Bearer") yalnızca varsayılan TokenLookup değeriyle kullanılır |
"Bearer" |
KeyFunc | func() jwt.Keyfunc |
Jeton doğrulaması için genel anahtarı sağlamak için kullanıcı tanımlı bir işlev | jwtKeyFunc |
JWKSetURLs | []string |
JWT ayrıştırmak için kullanılan benzersiz JSON Web Key (JWK) Set URL'lerinin bir dilimi | nil |
HS256 Örneği
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()
// Giriş rotası
app.Post("/login", login)
// Kimlik doğrulama olmadan erişilebilir rotası
app.Get("/", accessible)
// JWT ara yazılımı
app.Use(jwtware.New(jwtware.Config{
SigningKey: jwtware.SigningKey{Key: []byte("secret")},
}))
// Kısıtlı rotası
app.Get("/restricted", restricted)
app.Listen(":3000")
}
func login(c *fiber.Ctx) error {
user := c.FormValue("user")
pass := c.FormValue("pass")
// Yetkilendirilmemiş hata fırlatma
if user != "john" || pass != "doe" {
return c.SendStatus(fiber.StatusUnauthorized)
}
// Talepler oluşturma
claims := jwt.MapClaims{
"name": "John Doe",
"admin": true,
"exp": time.Now().Add(time.Hour * 72).Unix(),
}
// Jeton oluşturma
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
// Kodlanmış jeton oluşturma ve yanıt olarak gönderme
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("Erişilebilir")
}
func restricted(c *fiber.Ctx) error {
user := c.Locals("user").(*jwt.Token)
claims := user.Claims.(jwt.MapClaims)
name := claims["name"].(string)
return c.SendString("Hoş geldin " + name)
}
HS256 Test
Username ve şifre ile giriş yaparak bir belirteç elde edin.
curl --data "user=john&pass=doe" http://localhost:3000/login
Cevap
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0NjE5NTcxMzZ9.RB3arc4-OyzASAaUhC2W3ReWaXAt_z2Fd3BN4aWTgEY"
}
Yetkilendirme başlığında belirteceği kullanarak kısıtlanmış kaynağı isteyin.
curl localhost:3000/restricted -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0NjE5NTcxMzZ9.RB3arc4-OyzASAaUhC2W3ReWaXAt_z2Fd3BN4aWTgEY"
Cevap
Hoş geldiniz John Doe
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 (
// Açıkçası, bu sadece bir test örneğidir. Üretim ortamında bunu yapmayın.
// Üretimde, anahtar çiftini önceden oluşturmalısınız.
// Özel anahtarı hiçbir GitHub deposuna eklemeyin.
privateKey *rsa.PrivateKey
)
func main() {
app := fiber.New()
// Gösterim amaçlı, program her çalıştığında new private/public key pair'a oluşturun. Yukarıdaki notu görün.
rng := rand.Reader
var err error
privateKey, err = rsa.GenerateKey(rng, 2048)
if err != nil {
log.Fatalf("rsa.GenerateKey:%v", err)
}
// Giriş rotası
app.Post("/login", login)
// Kimlik doğrulama olmayan rota
app.Get("/", accessible)
// JWT ara yazılım
app.Use(jwtware.New(jwtware.Config{
SigningKey: jwtware.SigningKey{
JWTAlg: jwtware.RS256,
Key: privateKey.Public(),
},
}))
// Kısıtlanmış rota
app.Get("/restricted", restricted)
app.Listen(":3000")
}
func login(c *fiber.Ctx) error {
user := c.FormValue("user")
pass := c.FormValue("pass")
// Yetkisiz hata fırlat
if user != "john" || pass != "doe" {
return c.SendStatus(fiber.StatusUnauthorized)
}
// Talepleri oluştur
claims := jwt.MapClaims{
"name": "John Doe",
"admin": true,
"exp": time.Now().Add(time.Hour * 72).Unix(),
}
// Belirteç oluştur
token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
// Kodlanmış belirteç oluştur ve cevap olarak gönder
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("Erişilebilir")
}
func restricted(c *fiber.Ctx) error {
user := c.Locals("user").(*jwt.Token)
claims := user.Claims.(jwt.MapClaims)
name := claims["name"].(string)
return c.SendString("Hoş geldiniz " + name)
}
RS256 Test
RS256, temelde yukarıdaki HS256 testiyle aynıdır.
JWK Set Test
Bu testler, temel JWT testleriyle aynıdır, ancak JWKSetURLs adresinde JWK Set biçiminde geçerli genel anahtar setleri gerektirmektedir.
Özel KeyFunc Örneği
KeyFunc, token doğrulaması için kullanılan genel anahtarları sağlamak için kullanıcı tanımlı bir işlevi tanımlar. Bu işlev, imza algoritmasını doğrulamak ve doğru anahtarı seçmekten sorumludur. Eğer token harici bir taraf tarafından verilmişse, kullanıcı tanımlı KeyFunc yararlı olabilir.
Kullanıcı tanımlı KeyFunc sağlandığında, SigningKey, SigningKeys ve SigningMethod yoksayılır. Bu, token doğrulama anahtarlarını sağlamanın üç seçeneğinden biridir. Öncelik sırası kullanıcı tanımlı KeyFunc, SigningKeys ve SigningKey'dir. Eğer ne SigningKeys ne de SigningKey sağlanmamışsa, bu işlev sağlanmalıdır. Varsayılan olarak, içsel uygulama kullanılarak imza algoritmasını doğrulamak ve uygun anahtarı seçmek için uygulanır.
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) {
// İmza yönteminin doğru olup olmadığını kontrol et
if t.Method.Alg() != jwtware.HS256 {
return nil, fmt.Errorf("Beklenmeyen jwt imza yöntemi=%v", t.Header["alg"])
}
// İmza anahtarının özel yüklenmesini uygula, örn. veritabanından yükle
signingKey := "gizli"
return []byte(signingKey), nil
}
}