|
1 | | -<ComingSoon /> |
| 1 | +--- |
| 2 | +title: "JWT (JSON Web Tokens) Explained" |
| 3 | +sidebar_label: "3. JWT Tokens" |
| 4 | +sidebar_position: 3 |
| 5 | +description: "Learn how to use JSON Web Tokens for stateless authentication in your MERN stack applications." |
| 6 | +tags: ["authentication", "JWT", "json web tokens", "security", "full-stack development"] |
| 7 | +keywords: ["JWT", "json web tokens", "authentication", "Node.js", "Express", "MongoDB", "PostgreSQL", "jsonwebtoken", "token-based authentication"] |
| 8 | +--- |
| 9 | + |
| 10 | +A **JWT** is a compact, URL-safe way of representing claims to be transferred between two parties. In simple terms: it is a digital ID card that proves who you are. |
| 11 | + |
| 12 | +## 1. Why use JWT? |
| 13 | + |
| 14 | +In modern web apps (like the ones we build at the Hub), we want our backend to be **Stateless**. |
| 15 | +* **Stateful:** The server must remember every logged-in user in its RAM. (Heavy and hard to scale). |
| 16 | +* **Stateless (JWT):** The server doesn't remember you. You carry your own "Identity" in your token. The server just verifies the signature on the token. |
| 17 | + |
| 18 | + |
| 19 | +## 2. Anatomy of a JWT |
| 20 | + |
| 21 | +A JWT looks like a long string of gibberish separated by two dots: `xxxxx.yyyyy.zzzzz`. It has three parts: |
| 22 | + |
| 23 | +1. **Header:** Tells the server what algorithm is used (e.g., HS256). |
| 24 | +2. **Payload:** Contains the user data (claims) like `userId` or `username`. **Warning:** Never put passwords here! This part is encoded, not encrypted (anyone can read it). |
| 25 | +3. **Signature:** This is the secret sauce. It is a combination of the Header, Payload, and a **Secret Key** known only to your server. |
| 26 | + |
| 27 | +> If a user tries to change the `userId` in the Payload, the **Signature** will no longer match, and the server will reject the token! |
| 28 | +
|
| 29 | +## 3. Using JWT in Node.js |
| 30 | + |
| 31 | +We use the `jsonwebtoken` library to handle tokens. |
| 32 | + |
| 33 | +### Installation |
| 34 | + |
| 35 | +```bash |
| 36 | +npm install jsonwebtoken |
| 37 | +``` |
| 38 | + |
| 39 | +### Generating a Token (On Login) |
| 40 | + |
| 41 | +When a user successfully logs in, you "Sign" a token and send it to them. |
| 42 | + |
| 43 | +```javascript title="generateToken.js" |
| 44 | +const jwt = require('jsonwebtoken'); |
| 45 | + |
| 46 | +const token = jwt.sign( |
| 47 | + { userId: user._id, role: 'student' }, // Payload |
| 48 | + process.env.JWT_SECRET, // Your Secret Key |
| 49 | + { expiresIn: '1h' } // Token expires in 1 hour |
| 50 | +); |
| 51 | + |
| 52 | +res.json({ token }); |
| 53 | + |
| 54 | +``` |
| 55 | + |
| 56 | +### Verifying a Token (Middleware) |
| 57 | + |
| 58 | +When the user wants to access a "Protected" route, they send the token in the **Header**. Your server verifies it: |
| 59 | + |
| 60 | +```javascript title="verifyToken.js" |
| 61 | +const verifyToken = (req, res, next) => { |
| 62 | + const token = req.header('Authorization'); |
| 63 | + |
| 64 | + if (!token) return res.status(401).send("Access Denied!"); |
| 65 | + |
| 66 | + try { |
| 67 | + const verified = jwt.verify(token, process.env.JWT_SECRET); |
| 68 | + req.user = verified; // Add user info to the request object |
| 69 | + next(); // Move to the actual route |
| 70 | + } catch (err) { |
| 71 | + res.status(400).send("Invalid Token!"); |
| 72 | + } |
| 73 | +}; |
| 74 | + |
| 75 | +``` |
| 76 | + |
| 77 | +## 4. Where to store the Token? |
| 78 | + |
| 79 | +As a developer, you have two main choices for where the browser should save the token: |
| 80 | + |
| 81 | +| Location | Security | Complexity | |
| 82 | +| --- | --- | --- | |
| 83 | +| **LocalStorage** | Vulnerable to XSS (Scripts can steal it). | Very Easy to use. | |
| 84 | +| **HttpOnly Cookie** | Immune to XSS. (Best Practice). | Requires more setup. | |
| 85 | + |
| 86 | +At **CodeHarborHub**, we recommend starting with LocalStorage for learning, but moving to **HttpOnly Cookies** for professional projects. |
| 87 | + |
| 88 | +## 5. The "Secret Key" Rule |
| 89 | + |
| 90 | +Your `JWT_SECRET` is the most important piece of data in your backend. |
| 91 | + |
| 92 | +* If someone gets your secret, they can create tokens for **any user** and log in as anyone (even the Admin!). |
| 93 | +* **Always** store your secret in a `.env` file and **never** push it to GitHub. |
| 94 | + |
| 95 | +## Practice: The Token Decoder |
| 96 | + |
| 97 | +1. Go to [JWT.io](https://jwt.io/). |
| 98 | +2. Paste a token you generated in your code. |
| 99 | +3. Look at the "Payload" on the right. Can you see your `userId`? |
| 100 | +4. Try changing a single letter in the token string. Watch how the "Signature Invalid" warning appears! |
| 101 | + |
| 102 | +:::info Token Expiration |
| 103 | +Always set an expiration time (like `1h` or `7d`). If a token is ever stolen, it won't be useful forever. For "Master" level security, look into **Refresh Tokens** later! |
| 104 | +::: |
0 commit comments