رمزگذار JWT
ساخت و امضای JSON Web Token با HS256، HS384، HS512
هدر
پیلود
کلید مخفی
JWT رمزگذاریشده
کلید مخفی شما هرگز مرورگر را ترک نمیکند. تمام عملیات امضا در سمت کلاینت انجام میشود.
رمزگذاری JWT چیست؟
رمزگذاری JWT فرایند ساخت یک JSON Web Token است — یک رشته فشرده و URL-safe که مجموعهای از کلیمها را با یک کلید رمزنگاری امضا کرده نگه میدارد. نتیجه یک توکن سهبخشی (header.payload.signature) است که بر اساس RFC 7519 تعریف شده و سرورها میتوانند بدون نگهداری وضعیت نشست آن را تأیید کنند. رمزگذاری JWT آنلاین به شما امکان میدهد توکنها را مستقیماً در مرورگر برای آزمایش و توسعه بسازید و امضا کنید.
هدر الگوریتم امضا (مثلاً HS256) و نوع توکن را اعلام میکند. پیلود حاوی کلیمها است — جفتهای کلید-مقدار مانند موضوع (sub)، زمان انقضا (exp) و هر داده سفارشی که برنامه شما نیاز دارد. هر دو بخش بهصورت JSON سریال میشوند، سپس با base64url رمزگذاری میگردند. امضا روی هدر و پیلود رمزگذاریشده با کلید مخفی محاسبه میشود و هر سه بخش را به هم متصل میکند.
برخلاف کوکیهای نشست، JWTها خودکفا هستند: تأییدکننده نیازی به پرسوجو از پایگاه داده یا فراخوانی سرویس خارجی ندارد. این ویژگی باعث شده احراز هویت مبتنی بر JWT در REST APIها، میکروسرویسها و برنامههای تکصفحهای که مجوزدهی بدون وضعیت تأخیر را کاهش داده و مقیاسپذیری افقی را ساده میکند، بسیار محبوب باشد.
چرا از رمزگذار JWT استفاده کنیم؟
تولید JWT بهصورت دستی نیازمند رمزگذاری base64url، سریالسازی JSON و محاسبه HMAC است. این ابزار هر سه مرحله را فوری انجام میدهد تا بتوانید روی درستی کلیمها تمرکز کنید.
موارد استفاده از رمزگذار JWT
مقایسه الگوریتمهای HMAC: HS256 در برابر HS384 در برابر HS512
هر سه الگوریتم از HMAC (کد احراز هویت پیام مبتنی بر هش) با یک کلید مخفی مشترک استفاده میکنند. تفاوت در تابع هش زیرین است که طول امضا و حاشیه امنیتی را تحت تأثیر قرار میدهد. برای اکثر برنامهها HS256 امنیت کافی فراهم میکند. HS384 یا HS512 را انتخاب کنید وقتی الزامات انطباق (مثلاً FIPS-140) هش قویتری را الزامی میکنند یا وقتی توکنهای شما تصمیمات مجوزدهی با ارزش بالا حمل میکنند.
| الگوریتم | هش | امضا | سرعت | استفاده معمول |
|---|---|---|---|---|
| HS256 | SHA-256 | 32 B | Fastest | General purpose, default for most libraries |
| HS384 | SHA-384 | 48 B | Fast | Higher security margin, FIPS-140 compliant |
| HS512 | SHA-512 | 64 B | Fast | Maximum HMAC security, large payloads |
مرجع کلیمهای استاندارد JWT
RFC 7519 هفت کلیم ثبتشده را تعریف میکند. هیچکدام الزامی نیستند، اما استفاده صحیح از آنها قابلیت همکاری و امنیت را بهبود میبخشد. کلیم exp بهویژه مهم است — توکنهای بدون انقضا تا زمانی که کلید مخفی تعویض نشود، نامحدود معتبر هستند.
| کلیم | نام | توضیح | مثال |
|---|---|---|---|
| iss | Issuer | Who issued the token | "auth.example.com" |
| sub | Subject | Who the token represents | "user-123" |
| aud | Audience | Intended recipient service | "api.example.com" |
| exp | Expiration | Unix timestamp — token invalid after this time | 1717203600 |
| nbf | Not Before | Unix timestamp — token invalid before this time | 1717200000 |
| iat | Issued At | Unix timestamp when the token was created | 1717200000 |
| jti | JWT ID | Unique token identifier for revocation tracking | "a1b2c3d4" |
رمزگذاری JWT در کد
این مثالها نحوه ساخت و امضای JWT بهصورت برنامهنویسی را نشان میدهند. هر قطعه کد یک توکن معتبر امضاشده با HS256 تولید میکند. برای سیستمهای تولیدی، همیشه کلیم exp را تنظیم کنید و از یک کلید مخفی تصادفی رمزنگاریشده با حداقل ۲۵۶ بیت استفاده کنید.
async function signJWT(payload, secret, alg = 'HS256') {
const header = { alg, typ: 'JWT' }
const enc = new TextEncoder()
// Base64url encode header and payload
const b64url = (obj) =>
btoa(JSON.stringify(obj)).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '')
const h = b64url(header)
const p = b64url(payload)
// Sign with HMAC-SHA256
const key = await crypto.subtle.importKey(
'raw', enc.encode(secret),
{ name: 'HMAC', hash: 'SHA-256' }, false, ['sign']
)
const sig = await crypto.subtle.sign('HMAC', key, enc.encode(`${h}.${p}`))
const s = btoa(String.fromCharCode(...new Uint8Array(sig)))
.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '')
return `${h}.${p}.${s}`
}
// Usage
const token = await signJWT(
{ sub: 'user-123', name: 'Alice', iat: Math.floor(Date.now() / 1000) },
'your-256-bit-secret'
)
// → "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOi..."import jwt
import time
payload = {
"sub": "user-123",
"name": "Alice",
"iat": int(time.time()),
"exp": int(time.time()) + 3600, # expires in 1 hour
}
# Sign with HS256 (default)
token = jwt.encode(payload, "your-256-bit-secret", algorithm="HS256")
# → "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOi..."
# Verify and decode
decoded = jwt.decode(token, "your-256-bit-secret", algorithms=["HS256"])
# → {"sub": "user-123", "name": "Alice", "iat": 1717200000, "exp": 1717203600}const jwt = require('jsonwebtoken')
const payload = {
sub: 'user-123',
name: 'Alice',
role: 'admin',
}
// Sign — iat is added automatically
const token = jwt.sign(payload, 'your-256-bit-secret', {
algorithm: 'HS256',
expiresIn: '1h', // sets exp claim
issuer: 'auth.example.com', // sets iss claim
})
// Verify
const decoded = jwt.verify(token, 'your-256-bit-secret')
// → { sub: 'user-123', name: 'Alice', role: 'admin', iat: ..., exp: ... }package main
import (
"fmt"
"time"
"github.com/golang-jwt/jwt/v5"
)
func main() {
claims := jwt.MapClaims{
"sub": "user-123",
"name": "Alice",
"iat": time.Now().Unix(),
"exp": time.Now().Add(time.Hour).Unix(),
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
signed, _ := token.SignedString([]byte("your-256-bit-secret"))
fmt.Println(signed)
// → eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOi...
}