ফাইবার JWT

এই JWT মিডলওয়্যার বিন্যাস (middleware) একটি JSON Web Token (JWT) অথেন্টিকেশন মিডলওয়্যার রিটার্ন করে। একটি বৈধ টোকেনের জন্য, এটি Ctx.Locals এ ব্যবহারকারী সেট করে এবং পরবর্তী হ্যান্ডলার কল করে। একটি অবৈধ টোকেনের জন্য, এটি "401 - অননুমোদিত" ত্রুটি রিটার্ন করে। এবং মিসিং টোকেনের জন্য, এটি "400 - খারাপ অনুরোধ" ত্রুটি রিটার্ন করে।

নোট: গো ভার্শন 1.19 বা তার উপরে প্রয়োজন

ইনস্টলেশন

এই মিডলওয়্যারটি 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

স্বাক্ষর

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

কনফিগারেশন

প্রোপার্টি টাইপ বিবরণ ডিফল্ট ভ্যালু
Filter func(*fiber.Ctx) bool মিডলওয়্যার মিস করতে একটি ফাংশন সংজ্ঞায়িত করে nil
SuccessHandler func(*fiber.Ctx) error বৈধ টোকেনের উপরে বাস্তবায়ন করার জন্য একটি ফাংশন নির্ধারণ করে nil
ErrorHandler func(*fiber.Ctx, error) error অবৈধ টোকেনের উপরে বাস্তবায়ন করার জন্য একটি ফাংশন নির্ধারণ করে 401 অবৈধ বা মেয়াদ উত্তীর্ণ JWT
SigningKey interface{} এমন অঙ্কনী কি নির্ধারণ করা টোকেন যাচাই করার জন্য ব্যবহৃত হয়। যদি SigningKeys এর দৈর্ঘ্য 0 হয়, তবে এটি এক ফলব্যবহার হিসেবে ব্যবহার হয় nil
SigningKeys map[string]interface{} টোকেন পরীক্ষা করার জন্য ব্যবহৃত অঙ্কনী কী এর ম্যাপিং যা kid ফিল্ড সহ টোকেন যাচাই করার জন্য ব্যবহৃত nil
ContextKey string ব্যবহারকারী তথ্য টোকেন থেকে সংগ্রহ করার জন্য ব্যবহৃত সংদহন কি "user"
Claims jwt.Claim টোকেনের বিস্তৃত দাবি তথ্য যা টোকেনের বিষয়বস্তু সংজ্ঞায়িত করে jwt.MapClaims{}
TokenLookup string টোকেন কাটা নির্ধারণ করার জন্য : ফরম্যাটের একটি স্ট্রিং ব্যবহৃত হয় "header:Authorization"
AuthScheme string অথোরাইজেশন হেডারে ব্যবহৃত AuthScheme। ডিফল্ট মান ("Bearer") শুধুমাত্র ডিফল্ট TokenLookup মানের সাথে ব্যবহৃত হয় "Bearer"
KeyFunc func() jwt.Keyfunc টোকেন যাচাই করার জন্য পাবলিক কী সরবরাহ করার জন্য ব্যবহারকারী সংরক্ষিত ফাংশন jwtKeyFunc
JWKSetURLs []string পার্স করার জন্য ব্যবহৃত অদ্ভুত JSON Web Key (JWK) সেট URLs এর স্লাইস 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("অ্যাক্সেসযোগ্য")
}

func restricted(c *fiber.Ctx) error {
	user := c.Locals("user").(*jwt.Token)
	claims := user.Claims.(jwt.MapClaims)
	name := claims["name"].(string)
	return c.SendString("স্বাগতম " + name)
}

HS256 পরীক্ষা

ব্যবহারকারীর নাম এবং পাসওয়ার্ড দিয়ে লগইন করে একটি টোকেন পেতে।

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

সাক্ষাতকার

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

সীমাবদ্ধ সম্পদ অনুমোদনে অনুরোধ করতে অনুমোদন শিরোনামে টোকেনটি ব্যবহার করে।

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

সাক্ষাতকার

স্বাগতম 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 (
	// ব্যাপারটি স্বয়ংক্রিয়ভাবে একটি পরীক্ষামূলক উদাহরণ। নির্মাণে, আপনার অগ্রৈগুণ্যে প্রাইভেট কী জেনারেট করতে হবে।
	// কোনও 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("প্রবেশযোগ্য")
}

func restricted(c *fiber.Ctx) error {
	user := c.Locals("user").(*jwt.Token)
	claims := user.Claims.(jwt.MapClaims)
	name := claims["name"].(string)
	return c.SendString("স্বাগতম " + name)
}

RS256 পরীক্ষা

RS256 প্রায়ই উপরোক্ত HS256 পরীক্ষার মতা।

JWK সেট টেস্ট

এই পরীক্ষা গুলি মৌলিক JWT পরীক্ষার মত, তবে এটি JWKSetURLs ফরম্যাটে বৈধ পাবলিক কী সেটগুলি প্রয়োজন।

কাস্টম KeyFunc উদাহরণ

KeyFunc টি একটি ব্যবহারকারী-নির্ধারিত ফাংশন সংজ্ঞায়িত করে যা টোকেন যাচাই করার জন্য পাবলিক কী প্রদান করতে ব্যবহৃত হয়। এই ফাংশনটি স্বাক্ষর কৌশলটি যাচাই করার জন্য দায়িত্বশীল এবং সঠিক কীটি নির্বাচন করার জন্য দায়িত্বশীল। যদি টোকেনটি একটি বাহ্যিক পক্ষ দ্বারা ইস্যু করা হয়, তবে ব্যবহারকারী নির্ধারিত KeyFunc দরকার হতে পারে।

যখন ব্যবহারকারী-নির্ধারিত KeyFunc প্রদান করা হয়, তখন SigningKey, SigningKeys, এবং SigningMethod এগুলি উপেক্ষা করা হবে। টোকেন যাচাই কী দেওয়ার তিনটি অপশন মধ্যে এটি একটি। অগ্রাধিকার অর্ডার হ'ল ব্যবহারকারী-নির্ধারিত KeyFunc, 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("অপ্রত্যাশিত jwt সাইনিং মেথড=%v", t.Header["alg"])
		}

		// TODO স্বনির্ধারিত সাইনিং কীর লোডিং ইমপ্লিমেন্ট করুন, উদাহরণস্বরূপ, ডাটাবেস থেকে লোড করুন
    signingKey := "গোপনীয়"

		return []byte(signingKey), nil
	}
}