חזרה למחברת
IT & Security10 דקות קריאה

JWT מההתחלה: למה צריך טוקן, איך מאבטחים ומיישמים בעזרת AI

להבין התחברות, חתימה והרשאות דרך דוגמת B2B. קוד מלא ב-JavaScript, Python ו-PHP, בדיקות שליליות ופרומפטים באנגלית.

למה זה שימושי?

דמיינו אפליקציית אירועים לנייד שפונה ל-API של חשבוניות. לאחר ההתחברות המשתמש מבצע בקשות רבות בלי לשלוח שוב סיסמה. טוקן גישה קצר יכול לשאת הצהרה חתומה על המשתמש שכבר אומת. השרת בודק אותה לפני טיפול בבקשה. זה שימושי ללקוחות ניידים או לכמה שירותים שצריכים לבדוק גישה בנפרד.

JWT הוא פורמט ולא מערכת התחברות שלמה. באתר רגיל סשן שרת עם עוגייה אטומה עשוי להיות פשוט יותר. בשני המקרים עדיין צריך הרשאות. בסוף המדריך תוכלו להסביר את זרימת הטוקן, להריץ שלוש גרסאות, לדחות טוקנים לא תקינים ולבקש מה-AI שינוי שאפשר לבדוק. הפרויקט הוא תרגיל מקומי ללא נקודת התחברות אמיתית.

1. מההתחברות לחשבונית

מערכת מהימנה מאמתת את המשתמש ורק אחר כך מנפיקה טוקן. הלקוח שולח אותו ב-HTTPS, בדרך כלל בכותרת Authorization: Bearer. ה-API בודק חתימה ושדות, ואז הרשאה לחשבונית המסוימת.

המשתמש הפיקטיבי user-7 שייך ל-Acme. טוקן תקין שלו עדיין אינו מאפשר חשבונית של חברה אחרת, ובדוגמה גם לא חשבונית של משתמש אחר באותה חברה. אימות קובע מי אתם; הרשאה קובעת מה מותר לכם. הסתרת כפתור או מזהה שקשה לנחש אינם אכיפת הרשאות.

2. מבנה הטוקן וחוזה האבטחה

ל-JWT החתום כאן שלושה חלקי base64url: כותרת, תוכן וחתימה. התוכן קריא למחזיק בטוקן, לכן אין לשים בו סיסמאות, פרטי תשלום או מסמכים פרטיים. חתימה מגלה שינוי ואינה מצפינה את התוכן.

הפרופיל שלנו מחייב HS256 ומפתח שרת של לפחות 32 בתים אקראיים. iss הוא המנפיק, aud ה-API המקבל, sub מזהה המשתמש, tenant הארגון, ו-iat/exp הם זמני Unix שלמים בשניות. התוקף עד חמש דקות. typ המותאם nf-access+jwt מבדיל מטוקנים אחרים. אלה דרישות היישום שלנו ולא חובה לכל JWT.

ב-HS256 כל מאמת מחזיק גם בסוד שמאפשר להנפיק. למספר שירותים כדאי לשקול חתימה א-סימטרית ומפתחות ציבוריים/JWKS ממקור מהימן. קבעו מראש אלגוריתם ומקור מפתחות; כותרת שהתקבלה אינה רשאית לבחור כתובת או קובץ שרירותיים.

3. יישום בשפה שלכם

המודול המלא משתמש ב-jose. issue() מניח שזהות והארגון כבר אומתו בשרת. verify() בודק חתימה ופרופיל; canReadInvoice() בודק בעלות וארגון. בשירות אמיתי שומרים מפתח קבוע במנהל סודות, ולא יוצרים אותו בכל בקשה. בבדיקות משתמשים במפתחות אקראיים זמניים.

אותו פרופיל טוקן בשלוש שפות
import {SignJWT,jwtVerify} from 'jose';
const issuer='https://auth.example.test', audience='billing-api';
function checkKey(key){if(!(key instanceof Uint8Array)||key.length<32)throw new Error('Use at least 32 random bytes');}
export async function issue(subject,tenant,key){
 checkKey(key);
 if(!subject||!tenant)throw new Error('Missing identity');
 return new SignJWT({tenant}).setProtectedHeader({alg:'HS256',typ:'nf-access+jwt'})
  .setSubject(subject).setIssuer(issuer).setAudience(audience)
  .setIssuedAt().setExpirationTime('5m').sign(key);
}
export async function verify(token,key){
 checkKey(key);
 const {payload}=await jwtVerify(token,key,{
  algorithms:['HS256'],typ:'nf-access+jwt',issuer,audience,
  requiredClaims:['exp','iat','sub','tenant'],maxTokenAge:'5m',clockTolerance:0,
 });
 const now=Math.floor(Date.now()/1000);
 if(typeof payload.sub!=='string'||!payload.sub||typeof payload.tenant!=='string'||!payload.tenant||
  !Number.isInteger(payload.exp)||!Number.isInteger(payload.iat)||payload.iat>now||
  payload.exp<=payload.iat||payload.exp-payload.iat>300)throw new Error('Invalid access profile');
 return payload;
}
export function canReadInvoice(actor,invoice){
 return !!actor?.sub&&!!actor?.tenant&&actor.tenant===invoice?.tenant&&actor.sub===invoice?.owner;
}

4. Python עם PyJWT

הספרייה בודקת חתימה ושדות סטנדרטיים לפי התצורה. דרישה ששדה יופיע אינה מספיקה למשמעות העסקית שלו: בודקים גם זהות לא ריקה, זמנים שלמים, סוג ותוקף של חמש דקות. פענוח ללא אימות אינו מספק משתמש מהימן.

5. PHP ובדיקות מפורשות

PHP-JWT בודק חתימה וזמן; היישום חייב לבדוק גם מנפיק, קהל ופרופיל. כאן aud הוא בדיוק המחרוזת billing-api. ספק אחר עשוי לשלוח מערך: צריך להתאים חוזה במכוון ולא למחוק בדיקה רק כדי לקבל טוקן שונה.

6. שמירת טוקן ביישום אמיתי

אפשר להשתמש שוב בטוקן Bearer שנגנב עד פקיעתו או ביטולו. השתמשו ב-HTTPS, הסתירו Authorization בלוגים ואל תכניסו טוקנים לכתובות URL. עוגייה עם HttpOnly ו-Secure מונעת קריאה מ-JavaScript, אך צריך לבחור SameSite ולהגן מפני CSRF בבקשות שמשנות מידע. היא אינה מתקנת XSS. localStorage נגיש לסקריפט מוזרק; באפליקציה מקורית השתמשו באחסון המוגן של המערכת.

תוקף קצר אינו מימוש התנתקות. לביטול מיידי נדרשת בדיקת סשן/גרסה בשרת או מנגנון ביטול. טוקני רענון צריכים אחסון, סבב, זיהוי שימוש חוזר וביטול משלהם. החלפת מפתחות דורשת חפיפה מבוקרת. חברות בארגון יכולה להשתנות לפני exp, לכן פעולות רגישות צריכות לבדוק הרשאות עדכניות בשרת. אלה מחוץ לתרגיל.

7. הרצה ופירוש התוצאה

בחרו שפה אחת או השוו בין שלושתן. ה-ZIP מכיל מודולים, בדיקות וקובצי נעילה ל-JavaScript ול-PHP. ההתקנה זקוקה לסביבת השפה ולגישה למאגרי חבילות; אין צורך במפתח API או פרטי ייצור.

הבדיקות מאשרות שטוקן תקין מתקבל ושחתימה שגויה, תפוגה, שדות חסרים, מנפיק/קהל/סוג שגויים, זמן הנפקה עתידי, תוקף מופרז ומפתח קצר נדחים. נבדקת גם בעלות באותו ארגון. JavaScript ו-PHP מציגים 16 בדיקות תנאי מוצלחות; Python מריץ מתודת בדיקה עם המקרים המקבילים. אלו אינן בדיקות HTTP.

bash
# Choose ONE language; extract the ZIP into a new folder first.
# JavaScript / Node.js 22+
npm ci
npm test

# Python 3.9+ (macOS/Linux; Windows: .venv\Scripts\activate)
python3 -m venv .venv
. .venv/bin/activate
python -m pip install -r requirements.txt
python -m unittest test_python.py
python jwt_example.py

# PHP 8.1+ and Composer
composer install --no-plugins --no-scripts
php test_php.php
php jwt_example.php

8. יישום בעזרת AI עם ראיות

הפרומפט מבקש לבדוק קודם את המסגרת הקיימת. התאימו במכוון את המנפיק והקהל; אל תכניסו סוד חתימה לשיחה. בקשו שינוי קטן, פקודת בדיקה ותוצאה שבאמת התקבלה.

English AI prompt
Act as a senior application engineer. First inspect the existing authentication
framework and explain whether an opaque server session or a JWT is appropriate.
Do not replace a working authentication system just to introduce JWTs.
If JWT access tokens are justified, implement the provided local access profile:
pinned HS256, at least 32 random key bytes, issuer https://auth.example.test,
audience billing-api, typ nf-access+jwt, non-empty sub and tenant, required
integer iat and exp, maximum lifetime 300 seconds and no future issued-at.
Use jose, PyJWT or PHP-JWT according to the actual project language.
Issue tokens only after trusted authentication. Enforce object ownership and
tenant membership in server authorization on every relevant request.
Never derive a signing key, accepted algorithm or tenant from request JSON.
Propose browser storage, CSRF protection, logout/revocation and key rotation
for this application before coding. Do not log tokens or secrets.
Add negative tests for bad signatures, expiration, missing claims, wrong issuer,
audience and token type, another tenant and a non-owner. Report real test output.
Stop before deployment.

9. דוגמה לתשובת AI שימושית

זו דוגמה לצורת ראיות רצויה, לא טענה שבוצעה בדיקה של המערכת שלכם. אמירה כללית שהטוקנים בטוחים אינה ניתנת לאימות. תשובה טובה קושרת דרישה לקוד, בדיקה שלילית ושאלת אינטגרציה פתוחה. לאחר מכן השתמשו בפרומפט הביקורת.

Example and interpretation
Requirement: reject a token intended for another API.
Evidence: verify() supplies audience="billing-api".
Negative test: a correctly signed token with aud="other-api" is rejected.
Remaining gap: verify the real HTTP middleware invokes verify() on every route.
This example is an expected review format, not a certification.

10. מה בניתם ומה השלב הבא

יש לכם פרופיל שחוזר בשלוש שפות והפרדה בין זהות להרשאה. לפני שימוש אמיתי חברו אותו להתחברות ולתווך HTTP, ובדקו שגיאות, הרשאות עדכניות, עוגיות/CSRF, רענון, התנתקות וסבב מפתחות. התחילו מנקודת API אחת שמאשרת בעלות ודוחה גישה בין ארגונים.

English AI prompt
Review this local JWT implementation independently. Produce a table with:
requirement, exact code location, positive test, negative test and remaining gap.
Explain the difference between decoding, signature verification and authorization.
Check key entropy, algorithm pinning, required claims, issuer/audience/type,
short lifetime, server-derived identity, browser storage and token revocation.
Report confirmed defects separately from unverified integration assumptions.
Use only synthetic tokens. Never ask me to paste production credentials.

מקורות רשמיים והמשך לימוד

מכאן לפרויקט שלכם

הורידו את הקבצים, שמרו את המדריך או תנו לעוזר הפיתוח תיאור משימה מוכן.

מכינים את הפרויקט עם AI

העתיקו את הפרומפט באנגלית לעוזר הפיתוח. הוא כולל את המאמר, הקבצים הזמינים ושלבי ההכנה.

הצגת פרומפט ההכנה
AI setup prompt · English
Read this tutorial as reference material:
https://nethanelfitoussi.com/article/jwt-tokens-security-ai?lang=en

Goal: apply the documented workflow to my development project.
Read the existing project instructions, inspect the relevant files and explain the smallest useful setup.

Available starter files:
https://nethanelfitoussi.com/api/media/aba77d81-4cfd-4614-bca5-53015d625dff.zip
Download and inspect these files in a temporary folder before using them. Do not overwrite existing project instructions.

If I have not supplied a project folder, ask which development project to use. Do not invent a repository URL.

Additional project setup instructions:
Extract the supplied ZIP into a NEW folder. Read README.md before installing or running code.

Act as a senior application engineer. First inspect the existing authentication
framework and explain whether an opaque server session or a JWT is appropriate.
Do not replace a working authentication system just to introduce JWTs.
If JWT access tokens are justified, implement the provided local access profile:
pinned HS256, at least 32 random key bytes, issuer https://auth.example.test,
audience billing-api, typ nf-access+jwt, non-empty sub and tenant, required
integer iat and exp, maximum lifetime 300 seconds and no future issued-at.
Use jose, PyJWT or PHP-JWT according to the actual project language.
Issue tokens only after trusted authentication. Enforce object ownership and
tenant membership in server authorization on every relevant request.
Never derive a signing key, accepted algorithm or tenant from request JSON.
Propose browser storage, CSRF protection, logout/revocation and key rotation
for this application before coding. Do not log tokens or secrets.
Add negative tests for bad signatures, expiration, missing claims, wrong issuer,
audience and token type, another tenant and a non-owner. Report real test output.
Stop before deployment.

Review this local JWT implementation independently. Produce a table with:
requirement, exact code location, positive test, negative test and remaining gap.
Explain the difference between decoding, signature verification and authorization.
Check key entropy, algorithm pinning, required claims, issuer/audience/type,
short lifetime, server-derived identity, browser storage and token revocation.
Report confirmed defects separately from unverified integration assumptions.
Use only synthetic tokens. Never ask me to paste production credentials.

Adapt example paths, commands and acceptance criteria to this repository rather than assuming they match.

Give me a short plan, then make the agreed local changes and run the relevant checks. Report actual results and anything not verified. Stop before credentials, paid services, production changes, push, merge or deployment.
למקור הרשמיIETF · JWT security practices
JWTAuthenticationCybersecurityAI