# 🔐How JWT, Access Tokens & Refresh Tokens Work — Node.js vs AWS Lambda

## 🧠 What Are Access Tokens and Refresh Tokens?

| Token Type | Purpose | Lifespan | Stored Where |
| --- | --- | --- | --- |
| **Access Token** | Grants access to protected resources | Short-lived (e.g., 15 min) | In memory or localStorage |
| **Refresh Token** | Gets a new access token when expires | Long-lived (e.g., 7 days) | Secure httpOnly cookie / DB |

---

## 🎯 Real-Life Analogy: The Movie Hall Entry System

Imagine walking into a **movie theater**.

1. 🎟️ At the entrance, you show your **movie ticket** to the guard — this is your **Access Token**.  
    It allows you to enter and enjoy the movie.
    
2. 🕒 But the ticket is only valid for **one movie (say 2 hours)**. If you want to watch another movie or re-enter after stepping out, you **need a new ticket**.
    
3. 🤝 Instead of going to the main counter again and proving your identity (logging in), you carry a **VIP pass or membership card (Refresh Token)**.
    
4. 🎫 You present this **refresh token** at a special desk, and they issue you a **new movie ticket (new Access Token)** without requiring you to log in again.
    

---

### 🔐 Key Takeaway

* **Access Token = Movie Ticket**
    
    * Short-lived, used to access services
        
    * Shown often (like at the theatre gate)
        
* **Refresh Token = Membership Card**
    
    * Long-lived, used to get new access tokens
        
    * Hidden and securely stored
        

## 🔐 JWT Authentication Flow with Access + Refresh Tokens

1. **User logs in** ⇒ Receives both tokens
    
2. **An access token** is used to call protected APIs
    
3. If the access token **expires**, the client sends the **refresh token** to get a new access token
    
4. Refresh token is **stored securely** (e.g., in cookies)
    
5. If the refresh token is invalid or expired, ⇒ user must log in again
    

---

## 🏗️ Implementation in Node.js (Express)

### 📦 Install

```bash
npm install express jsonwebtoken cookie-parser
```

---

### 🔐 Token Functions (`auth.js`)

```javascript
const jwt = require("jsonwebtoken");

const ACCESS_SECRET = "access-secret";
const REFRESH_SECRET = "refresh-secret";

function generateTokens(user) {
  const accessToken = jwt.sign(user, ACCESS_SECRET, { expiresIn: "15m" });
  const refreshToken = jwt.sign(user, REFRESH_SECRET, { expiresIn: "7d" });
  return { accessToken, refreshToken };
}

function verifyAccess(token) {
  return jwt.verify(token, ACCESS_SECRET);
}

function verifyRefresh(token) {
  return jwt.verify(token, REFRESH_SECRET);
}

module.exports = { generateTokens, verifyAccess, verifyRefresh };
```

---

### 🧠 Express Server (`index.js`)

```javascript
const express = require("express");
const cookieParser = require("cookie-parser");
const { generateTokens, verifyAccess, verifyRefresh } = require("./auth");

const app = express();
app.use(express.json());
app.use(cookieParser());

app.post("/login", (req, res) => {
  const user = { email: req.body.email };
  const { accessToken, refreshToken } = generateTokens(user);
  res.cookie("refreshToken", refreshToken, { httpOnly: true });
  res.json({ accessToken });
});

app.get("/protected", (req, res) => {
  const auth = req.headers.authorization;
  if (!auth) return res.sendStatus(401);
  try {
    const user = verifyAccess(auth.split(" ")[1]);
    res.json({ message: "Access granted", user });
  } catch {
    res.status(403).json({ message: "Access token expired" });
  }
});

app.post("/refresh", (req, res) => {
  const refreshToken = req.cookies.refreshToken;
  if (!refreshToken) return res.sendStatus(401);
  try {
    const user = verifyRefresh(refreshToken);
    const { accessToken } = generateTokens(user);
    res.json({ accessToken });
  } catch {
    res.status(403).json({ message: "Refresh token invalid" });
  }
});
```

---

## 🚀 JWT with Refresh Token in AWS Lambda

Lambda is **stateless** — so no sessions! But you can use JWTs the same way.

### 🗂️ Structure

```javascript
pythonCopyEditlambda-jwt-auth/
├── handler.js
├── auth.js
```

---

### 🔐 `auth.js` (Same logic as Express)

```javascript
const jwt = require("jsonwebtoken");
const ACCESS_SECRET = "access-secret";
const REFRESH_SECRET = "refresh-secret";

function generateTokens(user) {
  const accessToken = jwt.sign(user, ACCESS_SECRET, { expiresIn: "15m" });
  const refreshToken = jwt.sign(user, REFRESH_SECRET, { expiresIn: "7d" });
  return { accessToken, refreshToken };
}

function verifyAccess(token) {
  return jwt.verify(token, ACCESS_SECRET);
}

function verifyRefresh(token) {
  return jwt.verify(token, REFRESH_SECRET);
}

module.exports = { generateTokens, verifyAccess, verifyRefresh };
```

---

### 🧠 `handler.js`

```javascript
const { generateTokens, verifyAccess, verifyRefresh } = require("./auth");

exports.login = async (event) => {
  const body = JSON.parse(event.body);
  const user = { email: body.email };
  const { accessToken, refreshToken } = generateTokens(user);

  return {
    statusCode: 200,
    headers: {
      "Set-Cookie": `refreshToken=${refreshToken}; HttpOnly; Path=/; Max-Age=604800`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ accessToken }),
  };
};

exports.protected = async (event) => {
  const authHeader = event.headers.authorization;
  try {
    const user = verifyAccess(authHeader.split(" ")[1]);
    return {
      statusCode: 200,
      body: JSON.stringify({ message: "Access granted", user }),
    };
  } catch {
    return { statusCode: 403, body: JSON.stringify({ error: "Token expired" }) };
  }
};

exports.refresh = async (event) => {
  const cookie = event.headers.cookie || "";
  const token = cookie.split("refreshToken=")[1];
  try {
    const user = verifyRefresh(token);
    const { accessToken } = generateTokens(user);
    return {
      statusCode: 200,
      body: JSON.stringify({ accessToken }),
    };
  } catch {
    return { statusCode: 403, body: JSON.stringify({ error: "Refresh token invalid" }) };
  }
};
```

---

## 📊 Node.js Server vs AWS Lambda (with Refresh Token)

| Feature | Node.js + JWT + Refresh Token | AWS Lambda + API Gateway + JWT |
| --- | --- | --- |
| Token Handling | In memory or a cookie | Via API Gateway headers/cookies |
| Refresh Logic | Simple via cookie | Cookie needs to be manually parsed |
| Storage Option | Can use Redis for refresh token blacklist | Store tokens in DB or skip blacklist |
| Deployment | Runs continuously | Cold start but lower cost |
| Use Case | Complex backend apps | Scalable microservices, low-traffic auth |

---

## 🧠 Summary

* **Access tokens** are short-lived and used to access protected resources.
    
* **Refresh tokens** are long-lived and used to generate new access tokens without login.
    
* JWTs help us implement **stateless** authentication in both **Node.js servers** and **AWS Lambda** functions.
    
* Store **refresh tokens securely** (e.g., httpOnly cookies) and **never expose them on the frontend**.
