secure-web-token 1.2.2 → 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +190 -21
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,42 +1,211 @@
|
|
|
1
1
|
# 🔐 Secure Web Token (SWT)
|
|
2
2
|
|
|
3
|
-
## About the Package
|
|
4
|
-
SWT is a secure token system that encrypts payloads and binds them to devices. Unlike JWT, it prevents token reuse on other devices.
|
|
3
|
+
## 1. About the Package
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
- JWT can be decoded easily.
|
|
8
|
-
- Tokens can be used on any device if leaked.
|
|
9
|
-
- SWT encrypts payloads and binds tokens to device fingerprints.
|
|
5
|
+
Secure Web Token (SWT) is a **next-generation authentication token system** designed for security-critical applications. Unlike traditional JWTs, SWT operates on a **Device Registration and Server-Side Session Model**, ensuring that tokens are intrinsically tied to specific devices and sessions.
|
|
10
6
|
|
|
11
|
-
|
|
7
|
+
Key highlights:
|
|
8
|
+
|
|
9
|
+
- **AES-256-GCM encryption**: Ensures payloads are fully encrypted, not just Base64 encoded.
|
|
10
|
+
- **Device fingerprint binding**: Tokens are locked to a device (or session) to prevent unauthorized reuse.
|
|
11
|
+
- **Server-side session store**: Device IDs and sessions are managed securely on the backend, never exposed to the browser.
|
|
12
|
+
- **Simple developer experience**: Easily integrate into Node.js applications with `sign` and `verify` functions.
|
|
13
|
+
|
|
14
|
+
SWT is ideal for **mission-critical applications** where security, controlled access, and device binding are required.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## 2. What Problem Does It Solve?
|
|
19
|
+
|
|
20
|
+
Traditional JWTs have several limitations:
|
|
21
|
+
|
|
22
|
+
- JWT payloads are only Base64 encoded, not encrypted. Anyone can decode them.
|
|
23
|
+
- If a token leaks, it can be reused from any device.
|
|
24
|
+
- No built-in mechanism to restrict tokens to specific devices.
|
|
25
|
+
- Cannot safely enforce single-device login without additional server logic.
|
|
26
|
+
|
|
27
|
+
**SWT addresses these issues by:**
|
|
28
|
+
|
|
29
|
+
- Fully encrypting token payloads using AES-256-GCM.
|
|
30
|
+
- Binding tokens to **device fingerprints** managed on the backend.
|
|
31
|
+
- Preventing token reuse from unauthorized devices.
|
|
32
|
+
- Supporting auto-generated device IDs for added security.
|
|
33
|
+
- Managing sessions server-side, so sensitive identifiers never reach the browser.
|
|
34
|
+
|
|
35
|
+
Use cases:
|
|
36
|
+
|
|
37
|
+
- Course platforms with anti-piracy requirements
|
|
38
|
+
- SaaS dashboards
|
|
39
|
+
- Admin panels with restricted access
|
|
40
|
+
- Any system requiring **device-bound authentication**
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## 3. Available Functions
|
|
45
|
+
|
|
46
|
+
### `sign()`
|
|
47
|
+
|
|
48
|
+
Creates a **secure, encrypted token**.
|
|
49
|
+
|
|
50
|
+
**Features:**
|
|
51
|
+
|
|
52
|
+
- Encrypts the payload completely
|
|
53
|
+
- Adds `iat` (issued at) and `exp` (expiry) timestamps
|
|
54
|
+
- Supports **device fingerprint binding**
|
|
55
|
+
- Can auto-generate a device ID
|
|
56
|
+
- Optional server-side session management
|
|
12
57
|
|
|
13
|
-
### sign()
|
|
14
|
-
Creates a secure token.
|
|
15
58
|
```ts
|
|
16
59
|
import { sign } from "secure-web-token";
|
|
17
|
-
|
|
18
|
-
|
|
60
|
+
|
|
61
|
+
const secret = "my-super-secret";
|
|
62
|
+
|
|
63
|
+
// Auto device registration + server session
|
|
64
|
+
const { token, sessionId } = sign(
|
|
65
|
+
{ userId: 1, role: "admin" },
|
|
66
|
+
secret,
|
|
67
|
+
{ fingerprint: true, store: "memory", expiresIn: 3600 }
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
console.log("TOKEN:", token);
|
|
71
|
+
console.log("SESSION ID (internal, not exposed to browser):", sessionId);
|
|
19
72
|
```
|
|
20
73
|
|
|
21
|
-
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
### `verify()`
|
|
77
|
+
|
|
22
78
|
Verifies and decrypts a token.
|
|
79
|
+
|
|
80
|
+
**Checks performed:**
|
|
81
|
+
|
|
82
|
+
- Token format integrity
|
|
83
|
+
- Signature correctness
|
|
84
|
+
- Expiry check
|
|
85
|
+
- Device fingerprint / session validation
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
import { verify, getStore } from "secure-web-token";
|
|
89
|
+
|
|
90
|
+
// Get the store instance (MemoryStore / Redis)
|
|
91
|
+
const store = getStore("memory");
|
|
92
|
+
|
|
93
|
+
try {
|
|
94
|
+
const payload = verify(token, secret, {
|
|
95
|
+
sessionId, // Server-side session ID
|
|
96
|
+
fingerprint: "abc", // Device fingerprint stored internally
|
|
97
|
+
store: "memory" // Must match the store used during sign()
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
console.log("USER DATA:", payload.data);
|
|
101
|
+
} catch (err) {
|
|
102
|
+
console.error("AUTH ERROR:", err.message);
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## 4. Server-Side Session Model (Recommended)
|
|
109
|
+
|
|
110
|
+
> In SWT v2+, **device verification is entirely server-side**.\
|
|
111
|
+
> This prevents attackers from copying tokens and device IDs from one browser to another.
|
|
112
|
+
|
|
113
|
+
**Workflow:**
|
|
114
|
+
|
|
115
|
+
1. **User logs in** → `sign()` generates token + server session
|
|
116
|
+
2. **Server stores session** internally (deviceId, fingerprint)
|
|
117
|
+
3. **Browser receives token + HttpOnly cookie** → cannot read device ID
|
|
118
|
+
4. **verify()**** checks session + fingerprint internally** → ensures single-device access
|
|
119
|
+
5. **Session revocation** automatically prevents token reuse
|
|
120
|
+
|
|
121
|
+
**Example Express backend:**
|
|
122
|
+
|
|
23
123
|
```ts
|
|
24
|
-
import
|
|
25
|
-
|
|
26
|
-
|
|
124
|
+
import express from "express";
|
|
125
|
+
import cookieParser from "cookie-parser";
|
|
126
|
+
import cors from "cors";
|
|
127
|
+
import { sign, verify, getStore } from "secure-web-token";
|
|
128
|
+
|
|
129
|
+
const app = express();
|
|
130
|
+
app.use(cors({ origin: true, credentials: true }));
|
|
131
|
+
app.use(cookieParser());
|
|
132
|
+
app.use(express.json());
|
|
133
|
+
|
|
134
|
+
const SECRET = "super-secret-key";
|
|
135
|
+
const store = getStore("memory");
|
|
136
|
+
|
|
137
|
+
// LOGIN
|
|
138
|
+
app.post("/login", (req, res) => {
|
|
139
|
+
const user = { userId: 1, name: "John" };
|
|
140
|
+
const { token, sessionId } = sign(user, SECRET, { fingerprint: true, store: "memory", expiresIn: 3600 });
|
|
141
|
+
|
|
142
|
+
res.cookie("swt_session", sessionId, { httpOnly: true, sameSite: "strict", secure: false });
|
|
143
|
+
res.json({ token });
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
// PROFILE
|
|
147
|
+
app.get("/profile", (req, res) => {
|
|
148
|
+
try {
|
|
149
|
+
const sessionId = req.cookies.swt_session;
|
|
150
|
+
const session = store.getSession(sessionId);
|
|
151
|
+
if (!session) throw new Error("Unauthorized or session expired");
|
|
152
|
+
|
|
153
|
+
const token = req.headers.authorization?.split(" ")[1];
|
|
154
|
+
const payload = verify(token, SECRET, { sessionId, fingerprint: session.fingerprint, store: "memory" });
|
|
155
|
+
res.json({ user: payload.data });
|
|
156
|
+
} catch (err) {
|
|
157
|
+
res.status(401).json({ error: err.message });
|
|
158
|
+
}
|
|
159
|
+
});
|
|
27
160
|
```
|
|
28
161
|
|
|
29
|
-
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## 5. Payload Structure (Internal)
|
|
165
|
+
|
|
166
|
+
```json
|
|
167
|
+
{
|
|
168
|
+
"data": {
|
|
169
|
+
"userId": 1,
|
|
170
|
+
"role": "admin"
|
|
171
|
+
},
|
|
172
|
+
"iat": 1768368114,
|
|
173
|
+
"exp": 1768369014,
|
|
174
|
+
"fp": "device-fingerprint" // stored server-side
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
> Note: The `fp` (fingerprint) and session ID are **not exposed to the browser**, making token copying attacks impossible.
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## 6. Installation
|
|
183
|
+
|
|
30
184
|
```bash
|
|
31
185
|
npm install secure-web-token
|
|
32
186
|
```
|
|
33
187
|
|
|
34
|
-
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## 7. Importing
|
|
191
|
+
|
|
35
192
|
```ts
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
193
|
+
// ESM
|
|
194
|
+
import { sign, verify, getStore } from "secure-web-token";
|
|
195
|
+
|
|
196
|
+
// CommonJS
|
|
197
|
+
const { sign, verify, getStore } = require("secure-web-token");
|
|
39
198
|
```
|
|
40
199
|
|
|
41
|
-
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## 8. Summary of Features
|
|
203
|
+
|
|
204
|
+
- 🔐 AES-256-GCM encryption
|
|
205
|
+
- 🔒 Server-side session + device binding
|
|
206
|
+
- ⏱ Expiry (`iat` + `exp`)
|
|
207
|
+
- 🛡 Prevents token reuse on unauthorized devices
|
|
208
|
+
- ⚡ Easy integration with Node.js / Express
|
|
209
|
+
- ✅ Auto-generated device IDs
|
|
210
|
+
- ✅ Fully optional server-side memory store
|
|
42
211
|
|