জেডডব্লিউটি সম্পর্কে পরিচিতি

JWT (JSON Web Token) হলো ওয়েবে অথেন্টিকেশনের জন্য একটি সংক্ষিপ্ত, স্ব-সমৃদ্ধ পদ্ধতি। এটি তিনটি অংশে বিভক্ত: হেডার, পেয়লোড, এবং স্বাক্ষর। হেডারে টোকেনের ধরন এবং এনক্রিপশন এলগোরিদম তথ্য থাকে, পেয়লোডে পাঠানোর ডেটা থাকে (সাধারণত কিছু অনুমতি তথ্য এবং ব্যবহারকারী সনাক্তকরণ সহ), এবং স্বাক্ষরটি টোকেনের সারাংশ এবং বৈধতা যাচাই করার জন্য ব্যবহৃত হয়।

JWT প্রধানত দুই সিনারিওতে ব্যবহৃত হয়:

  1. অথেন্টিকেশন: একবার একজন ব্যবহারকারী লগইন করে, পরবর্তী অনুরোধগুলিতে প্রতিটি সময় JWT থাকে, যা ব্যবহারকারীকে অনুমোদিত রুট, সেবা, এবং সম্পদে অ্যাক্সেস দেয়।
  2. তথ্য পরিবর্তন: JWT তথ্য সুরক্ষিতভাবে পার্টি মধ্যে প্রেরণ করার জন্য একটি ভাল পদ্ধতি, কারণ এগুলি ডিজিটাললি সাইন করা যেতে পারে, উদাহরণস্বরূপ পাবলিক/প্রাইভেট কী জোড়া ব্যবহার করে।

JWT ডাটা ফরম্যাট

JWT হলো সংক্ষিপ্ত, URL-নিরাপদ একটি মধ্যম যা পার্টিগুলি মধ্যে পরিবর্তনের জন্য প্রতিনিয়ত থাকে। একটি JWT প্রাকটিকally তিনটি অংশ থাকে, যা ডট (.) দ্বারা আলাদা করা থাকে, অর্থাৎ Header.Payload.Signature. পরবর্তীতে, আমরা এই তিনটি অংশের ডাটা ফরম্যাটের বিস্তারিত ধারণা দেব।

1. হেডার

হেডারে সাধারণত দুটি অংশ থাকে: টোকেনের ধরন—সাধারণত JWT, এবং ব্যবহৃত সিগনেচার বা এনক্রিপশন এলগোরিদম, উদাহরণস্বরূপ HMAC SHA256 বা RSA। হেডারটি JSON হিসাবে প্রতিষ্ঠাপিত এবং তারপর Base64Url ব্যবহারে স্ট্রিং হিসেবে কোডিং করা হয়। যেমন:

{
  "alg": "HS256",
  "typ": "JWT"
}

কোডিংের পরে, আপনি নিচের মত একটি স্ট্রিং পাবেন:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

2. পেয়লোড

পেয়লোডে সিলেক্টেড ক্লেমগুলির একটি সিরিজ থাকে, যা অবজেক্টের তথ্য (সাধারণত একটি ব্যবহারকারী) এবং অন্যান্য ডেটা শিল্পী। পেয়লোড মধ্যে একাধিক পূর্বনির্ধারিত ক্লেম থাকতে পারে (যা প্রাচীন ক্লেম বলা হয়), এবং কাস্টম ক্লেম (প্রাইভেট ক্লেম) থাকতে পারে।

প্রাচীন ক্লেমগুলি হতে পারে:

  • iss (ম্যান্ডেটরি): ইসুয়ার (Issuer)
  • exp (ম্যান্ডেটরি): মেয়াদ উত্তীর্ণের সময় (Expiration Time)
  • sub (ম্যান্ডেটরি): বিষয় (Subject)
  • aud (ম্যান্ডেটরি): শ্রোতা (Audience)
  • iat (ম্যান্ডেটরি): ইস্যুয়ের সময় (Issued At)
  • nbf (নন-ম্যান্ডেটরি): কার্যকর সময় (Not Before)
  • jti (নন-ম্যান্ডেটরি): JWT আইডি (Unique identity of the JWT)

একটি উদাহরণ পেয়লোড এমন হতে পারে (জেসন ফরম্যাটে):

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true,
  "iat": 1516239022
}

এই তথ্যটি ব্যবহৃত হয় Base64Url দ্বারা কোডিং এবং আপনি নিচের মত একটি স্ট্রিং পাবেন:

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0

3. স্বাক্ষর

স্বাক্ষর বিভাগটি উপরে উল্লিখিত দুটি কোডিং স্ট্রিং সাইন করার জন্য ব্যবহৃত হয়, যাতে ম্যাসেজটি প্রেরণের সময় এটি মুছা হতে না পারে। প্রথমে, আপনাকে যে কী (যদি HMAC SHA256 এলগোরিদম ব্যবহার করতে না হয়) স্পেসিফাই করতে হবে, এবং তারপর হেডার এবং পেয়লোড কোডিং করা স্ট্রিংগুলিকে সাইন করা জন্য হেডারে স্পেসিফাই ব্যবহার করতে হবে।

উদাহরণস্বরূপ, আপনার কাছে নিচের হেডার এবং পেয়লোড থাকলে:

Headকোডিং.পেয়লোডকোডিং

এবং এই কী ব্যবহার করে এগুলি সাইন করার জন্য প্সিডোকোডটি হতে পারে:

HMACSHA256(base64UrlEncode(হেডার) + "." + base64UrlEncode(পেয়লোড), গোপনীয়তা_কী)

ফলাফলে ব্যবহৃত সাইন করা স্ট্রিং একটিরও মত হতে পারে:

dBjftJeZ4CVPmTaoyL4IiArYfL4kH0jOspm6XwbcJXY

সম্পূর্ণ JWT

এই তিনটি অংশ ডট (.) দ্বারা আলাদা করে, সংকলন করে পুরো JWT তৈরি হয়:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.dBjftJeZ4CVPmTaoyL4IiArYfL4kH0jOspm6XwbcJXY

JWT মানসপতি খুব একেয় এবং পেলাগে কোনো তথ্য আপনার পেলাগানোর কারও জন্য, দিখানোর উদ্দেশ্যে JWT এর আকার কমানো এবং সিকিউরিটি কারনে, এটির মাধ্যমে সেরাহত তথ্য স্টোর না করা থাকে, এবং সিগনেচারের মাধ্যমে এই তথ্যের সংপূর্ণতা নিশ্চিত করা হয়।

গো JWT লাইব্রেরি ইনস্টল করা

গো কমিউনিটি জাস্টিস হ্যান্ডলিং জেডবলিউটি (JWT) এর জন্য github.com/golang-jwt/jwt প্যাকেজ প্রদান করে। এই লাইব্রেরি ইনস্টলেশন খুব সহজ, আপনার প্রজেক্ট ডিরেক্টরিতে নিচের কমান্ডটি রান করুন:

go get -u github.com/golang-jwt/jwt/v5

ইনস্টল করার পরে, আপনি এটি নিম্নলিখিত ভাবে আপনার import এ যুক্ত করতে পারেন:

import "github.com/golang-jwt/jwt/v5"

একটি সিম্পল টোকেন তৈরি

জেডবলিউটি ভাষা এবং এইচএস256 এলগোরিদম ব্যবহার করে সিম্পল JWT টোকেন তৈরি করতে নিম্নলিখিত পদক্ষেপ অনুসরণ করতে হবে:

প্রথমে, একটি নতুন Token অবজেক্ট জেনারেট করুন, এইচএস256 এলগোরিদম ব্যবহার করে:

token := jwt.New(jwt.SigningMethodHS256)

পরবর্তীতে, SignedString মেথড ব্যবহার করে এই টোকেনের একটি স্ট্রিং রিপ্রেজেন্টেশন জেনারেট করুন, স্বাক্ষরিত করার জন্য ব্যবহৃত কী পাস করে।

var mySigningKey = []byte("আপনার-256-বিট-গোপনীয় কী")
strToken, err := token.SignedString(mySigningKey)
if err != nil {
    log.Fatalf("একটি ত্রুটি ঘটেছে: %v", err)
}
fmt.Println(strToken)

এটি কোনও ক্লেম ছাড়া একটি সিম্পল টোকেন জেনারেট করবে।

প্যারামিটার সহ একটি টোকেন তৈরি

JWT এর একটি প্রধান কাজ হল তথ্য পরিবহন করা। এই তথ্যগুলি ক্লেম মাধ্যমে টোকেনে কোড করা হয়। উদাহরণস্বরূপ, আসুন কাস্টম ক্লেম তৈরি করা যাক:

// কাস্টম ক্লেম স্ট্রাকচার
type MyClaims struct {
	jwt.RegisteredClaims
	Username string `json:"username"`
	Admin    bool   `json:"admin"`
}

// কাস্টম ক্লেম সহ একটি টোকেন তৈরি করুন
claims := MyClaims{
    RegisteredClaims: jwt.RegisteredClaims{},
    Username: "আমার_ব্যবহারকারীর_নাম",
	Admin: true,
}

token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

// স্বাক্ষরিত করার জন্য গোপনীয় কী
var mySigningKey = []byte("আপনার-256-বিট-গোপনীয় কী")

// স্ট্রিং ফরম্যাটে টোকেন জেনারেট করুন
strToken, err := token.SignedString(mySigningKey)
if err != nil {
    log.Fatalf("ত্রুটি ঘটেছে: %v", err)
}

fmt.Println(strToken)

উপরের কোডে, আমরা MyClaims স্ট্রাকচারটি সংরক্ষণিত ক্লেম সহ সাধারণ প্রমাণগুলি ধারণ করব। তারপরে, আমরা এখনো SignedString ব্যবহার করে টোকেন স্ট্রিং জেনারেট করি।

টোকেনের প্যার্সিং এবং যাচাই করা

JWT এর পার্সিং এবং যাচাই করা খুব গুরুত্বপূর্ণ, এবং আপনি এটি নিম্নলিখিত মাধ্যমে করতে পারেন:

// আমরা একেই সামান্য MyClaims স্ট্রাকচারটি ব্যবহার করব
tokenString := "আপনার-JWT-স্ট্রিং"

// আমাদের যে ফাংশনটি ব্যবহার করে টোকেনটি পার্স করবে সে জন্যে একটি ফাংশন নিচে ডিফাইন করতে হবে যা jwt প্যাকেজ টোকেন স্ট্রিং পার্স করতে ব্যবহার করবে
keyFunc := func(t *jwt.Token) (interface{}, error) {
	// যাচাই করুন যে অপেক্ষা সাইনিং মেথড ব্যবহার করা হয়েছে
	if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {
	    return nil, fmt.Errorf("আশাজাদ সাইনিং মেথড: %v", t.Header["alg"])
	}
	// টোকেনের জন্য গোপনীয় কী, ফরম্যাট []byte, যা আগে স্বাক্ষরিত করার জন্য ব্যবহৃত হয়েছিল
	return mySigningKey, nil
}

// টোকেন পার্স করা
claims := &MyClaims{}
parsedToken, err := jwt.ParseWithClaims(tokenString, claims, keyFunc)
if err != nil {
	log.Fatalf("পার্সিং ত্রুটি: %v", err)
}

if !parsedToken.Valid {
    log.Fatalf("অবৈধ টোকেন")
}

// এই পর্যায়ে, parsedToken যাচাই করা হয়েছে, এবং আমরা আর ক্লেম পড়তে পারি
fmt.Printf("ব্যবহারকারী: %s, অ্যাডমিন: %v\n", claims.Username, claims.Admin)

উপরের কোডে, আমরা টোকেন স্ট্রিং, MyClaims ইন্সট্যান্স, এবং কী ফাংশন keyFunc কে jwt.ParseWithClaims কার্যকে পাস করে দিলাম। এই ফাংশনটি স্বাক্ষরিত হওয়ার পরে টোকেনটি যাচাই করবে এবং প্যার্স করবে, আদান প্রদান এবং যাচাইকরণ যদি টোকেন বৈধ হয় তবে claims ভ্যারিয়েবল পূরণ করবে।