@nauth-toolkit/storage-redis 0.1.3 → 0.1.6
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 +4 -271
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,276 +1,9 @@
|
|
|
1
1
|
# @nauth-toolkit/storage-redis
|
|
2
2
|
|
|
3
|
-
Redis storage adapter for nauth-toolkit using the
|
|
3
|
+
Redis storage adapter for nauth-toolkit using the redis package (node-redis)
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Preview Release Notice
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
## Features
|
|
10
|
-
|
|
11
|
-
- ✅ **Uses node-redis** - Official Redis client for Node.js
|
|
12
|
-
- ✅ **Redis Cluster Support** - Production-ready high-availability deployments
|
|
13
|
-
- ✅ **Multi-server compatible** - Shared Redis instance/cluster across all servers
|
|
14
|
-
- ✅ **High performance** - Optimized for transient state management
|
|
15
|
-
- ✅ **Automatic key prefixing** - All keys prefixed with `nauth_` to avoid collisions
|
|
16
|
-
- ✅ **TTL support** - Native Redis EXPIRE for automatic expiration
|
|
17
|
-
- ✅ **Production-ready** - Automatic topology discovery, command routing, and failover
|
|
18
|
-
|
|
19
|
-
## Installation
|
|
20
|
-
|
|
21
|
-
```bash
|
|
22
|
-
yarn add @nauth-toolkit/storage-redis redis
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
## Usage
|
|
26
|
-
|
|
27
|
-
### With Factory Functions (Recommended)
|
|
28
|
-
|
|
29
|
-
```typescript
|
|
30
|
-
import { createRedisStorageAdapter, createRedisClusterAdapter } from '@nauth-toolkit/nestjs';
|
|
31
|
-
|
|
32
|
-
// Single-instance Redis
|
|
33
|
-
AuthModule.forRoot({
|
|
34
|
-
jwt: { ... },
|
|
35
|
-
storageAdapter: createRedisStorageAdapter(process.env.REDIS_URL),
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
// Redis Cluster (for high-availability production)
|
|
39
|
-
AuthModule.forRoot({
|
|
40
|
-
jwt: { ... },
|
|
41
|
-
storageAdapter: createRedisClusterAdapter([
|
|
42
|
-
{ url: 'redis://redis-node-1:6379' },
|
|
43
|
-
{ url: 'redis://redis-node-2:6379' },
|
|
44
|
-
{ url: 'redis://redis-node-3:6379' },
|
|
45
|
-
]),
|
|
46
|
-
});
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
### With Manual Client Creation
|
|
50
|
-
|
|
51
|
-
```typescript
|
|
52
|
-
import { createClient, createCluster } from 'redis';
|
|
53
|
-
import { RedisStorageAdapter } from '@nauth-toolkit/storage-redis';
|
|
54
|
-
|
|
55
|
-
// Single-instance Redis
|
|
56
|
-
const redisClient = createClient({
|
|
57
|
-
url: process.env.NAUTH_REDIS_URL || 'redis://localhost:6379',
|
|
58
|
-
});
|
|
59
|
-
await redisClient.connect();
|
|
60
|
-
|
|
61
|
-
AuthModule.forRoot({
|
|
62
|
-
jwt: { ... },
|
|
63
|
-
storageAdapter: new RedisStorageAdapter(redisClient),
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
// Redis Cluster
|
|
67
|
-
const clusterClient = createCluster({
|
|
68
|
-
rootNodes: [
|
|
69
|
-
{ url: 'redis://redis-node-1:6379' },
|
|
70
|
-
{ url: 'redis://redis-node-2:6379' },
|
|
71
|
-
{ url: 'redis://redis-node-3:6379' },
|
|
72
|
-
],
|
|
73
|
-
});
|
|
74
|
-
await clusterClient.connect();
|
|
75
|
-
|
|
76
|
-
AuthModule.forRoot({
|
|
77
|
-
jwt: { ... },
|
|
78
|
-
storageAdapter: new RedisStorageAdapter(clusterClient),
|
|
79
|
-
});
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
### URL Format Support
|
|
83
|
-
|
|
84
|
-
Supports authentication in URL format:
|
|
85
|
-
- `redis://localhost:6379` (no auth)
|
|
86
|
-
- `redis://:password@localhost:6379` (password only)
|
|
87
|
-
- `redis://username:password@localhost:6379` (username + password)
|
|
88
|
-
- `rediss://localhost:6379` (TLS/SSL, with optional auth)
|
|
89
|
-
|
|
90
|
-
### Complete Example with Factory Functions
|
|
91
|
-
|
|
92
|
-
```typescript
|
|
93
|
-
import { Module } from '@nestjs/common';
|
|
94
|
-
import { createRedisStorageAdapter } from '@nauth-toolkit/nestjs';
|
|
95
|
-
import { AuthModule } from '@nauth-toolkit/nestjs';
|
|
96
|
-
|
|
97
|
-
@Module({
|
|
98
|
-
imports: [
|
|
99
|
-
AuthModule.forRoot({
|
|
100
|
-
jwt: {
|
|
101
|
-
accessToken: {
|
|
102
|
-
secret: process.env.JWT_SECRET,
|
|
103
|
-
expiresIn: '15m',
|
|
104
|
-
},
|
|
105
|
-
refreshToken: {
|
|
106
|
-
secret: process.env.JWT_REFRESH_SECRET,
|
|
107
|
-
expiresIn: '7d',
|
|
108
|
-
},
|
|
109
|
-
},
|
|
110
|
-
storageAdapter: createRedisStorageAdapter(process.env.REDIS_URL),
|
|
111
|
-
}),
|
|
112
|
-
],
|
|
113
|
-
})
|
|
114
|
-
export class AppModule {}
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
### With Dragonfly
|
|
118
|
-
|
|
119
|
-
Dragonfly is Redis-protocol compatible, so it works with the same clients:
|
|
120
|
-
|
|
121
|
-
```typescript
|
|
122
|
-
import { createClient } from 'redis';
|
|
123
|
-
import { RedisStorageAdapter } from '@nauth-toolkit/storage-redis';
|
|
124
|
-
|
|
125
|
-
// Dragonfly uses same protocol as Redis
|
|
126
|
-
const dragonflyClient = createClient({
|
|
127
|
-
url: 'dragonfly://localhost:6379', // or your Dragonfly URL
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
await dragonflyClient.connect();
|
|
131
|
-
|
|
132
|
-
AuthModule.forRoot({
|
|
133
|
-
jwt: { ... },
|
|
134
|
-
storageAdapter: new RedisStorageAdapter(dragonflyClient),
|
|
135
|
-
});
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
## Key Prefixing
|
|
139
|
-
|
|
140
|
-
All keys are automatically prefixed with `nauth_` to avoid collisions with other application keys:
|
|
141
|
-
|
|
142
|
-
- `ratelimit:user:123` → `nauth_:ratelimit:user:123`
|
|
143
|
-
- `refresh-lock:token-hash` → `nauth_:refresh-lock:token-hash`
|
|
144
|
-
- `used-token:hash` → `nauth_:used-token:hash`
|
|
145
|
-
|
|
146
|
-
## Client Requirements
|
|
147
|
-
|
|
148
|
-
The adapter validates that your Redis client has the following methods:
|
|
149
|
-
|
|
150
|
-
- `get(key)` - Get value
|
|
151
|
-
- `set(key, value, options?)` - Set value (with optional `{ EX: seconds }`)
|
|
152
|
-
- `del(key)` - Delete key
|
|
153
|
-
- `incr(key)` - Increment counter
|
|
154
|
-
- `decr(key)` - Decrement counter
|
|
155
|
-
- `expire(key, seconds)` - Set expiration
|
|
156
|
-
- `exists(key)` - Check existence
|
|
157
|
-
- `ttl(key)` - Get time to live
|
|
158
|
-
- `hget(key, field)` - Hash get
|
|
159
|
-
- `hset(key, field, value)` - Hash set
|
|
160
|
-
- `hgetall(key)` - Hash get all
|
|
161
|
-
- `hdel(key, ...fields)` - Hash delete
|
|
162
|
-
- `lpush(key, value)` - List push
|
|
163
|
-
- `lrange(key, start, stop)` - List range
|
|
164
|
-
- `llen(key)` - List length
|
|
165
|
-
- `ping()` - Health check
|
|
166
|
-
|
|
167
|
-
The `redis` package (node-redis) satisfies these requirements.
|
|
168
|
-
|
|
169
|
-
## Error Handling
|
|
170
|
-
|
|
171
|
-
The adapter includes connection health checks:
|
|
172
|
-
|
|
173
|
-
```typescript
|
|
174
|
-
const adapter = new RedisStorageAdapter(redisClient);
|
|
175
|
-
|
|
176
|
-
// Health check
|
|
177
|
-
const healthy = await adapter.isHealthy(); // Uses PING command
|
|
178
|
-
|
|
179
|
-
// Initialize (performs health check)
|
|
180
|
-
await adapter.initialize();
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
## Comparison with Other Adapters
|
|
184
|
-
|
|
185
|
-
| Feature | MemoryStorageAdapter | DatabaseStorageAdapter | RedisStorageAdapter |
|
|
186
|
-
|---------|---------------------|------------------------|---------------------|
|
|
187
|
-
| Multi-server | ❌ | ✅ | ✅ |
|
|
188
|
-
| Persistence | ❌ | ✅ | ✅ (optional) |
|
|
189
|
-
| Performance | ⚡⚡⚡ | ⚡⚡ | ⚡⚡⚡ |
|
|
190
|
-
| External dependency | ❌ | ❌ | ✅ (Redis) |
|
|
191
|
-
| Setup complexity | 🟢 Low | 🟡 Medium | 🟡 Medium |
|
|
192
|
-
| Redis Cluster | N/A | N/A | ✅ (high-availability) |
|
|
193
|
-
|
|
194
|
-
## Production Considerations
|
|
195
|
-
|
|
196
|
-
### Connection Pooling
|
|
197
|
-
|
|
198
|
-
The adapter doesn't manage connection pooling - your Redis client does. Configure pooling in your client:
|
|
199
|
-
|
|
200
|
-
**node-redis:**
|
|
201
|
-
```typescript
|
|
202
|
-
const redisClient = createClient({
|
|
203
|
-
url: process.env.NAUTH_REDIS_URL || 'redis://localhost:6379',
|
|
204
|
-
socket: {
|
|
205
|
-
reconnectStrategy: (retries) => {
|
|
206
|
-
if (retries > 10) return new Error('Too many retries');
|
|
207
|
-
return Math.min(retries * 100, 3000);
|
|
208
|
-
},
|
|
209
|
-
},
|
|
210
|
-
});
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
**node-redis with reconnection:**
|
|
214
|
-
```typescript
|
|
215
|
-
const redisClient = createClient({
|
|
216
|
-
url: process.env.NAUTH_REDIS_URL || 'redis://localhost:6379',
|
|
217
|
-
socket: {
|
|
218
|
-
reconnectStrategy: (retries) => {
|
|
219
|
-
if (retries > 10) return new Error('Too many retries');
|
|
220
|
-
return Math.min(retries * 100, 3000);
|
|
221
|
-
},
|
|
222
|
-
},
|
|
223
|
-
});
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
### TLS/SSL
|
|
227
|
-
|
|
228
|
-
Configure TLS in your Redis client:
|
|
229
|
-
|
|
230
|
-
```typescript
|
|
231
|
-
// TLS/SSL with authentication in URL
|
|
232
|
-
const redisClient = createClient({
|
|
233
|
-
url: process.env.NAUTH_REDIS_URL, // e.g., 'rediss://:password@host:6380'
|
|
234
|
-
socket: {
|
|
235
|
-
tls: true,
|
|
236
|
-
rejectUnauthorized: false, // Set to true in production with proper certs
|
|
237
|
-
},
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
// Or use rediss:// protocol in URL (TLS automatically enabled)
|
|
241
|
-
const redisClient = createClient({
|
|
242
|
-
url: 'rediss://:password@localhost:6380', // rediss:// = TLS enabled
|
|
243
|
-
});
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
### High Availability
|
|
247
|
-
|
|
248
|
-
For production, use Redis Cluster for high-availability:
|
|
249
|
-
|
|
250
|
-
```typescript
|
|
251
|
-
import { createRedisClusterAdapter } from '@nauth-toolkit/nestjs';
|
|
252
|
-
|
|
253
|
-
AuthModule.forRoot({
|
|
254
|
-
jwt: { ... },
|
|
255
|
-
storageAdapter: createRedisClusterAdapter([
|
|
256
|
-
{ url: 'redis://redis-node-1:6379' },
|
|
257
|
-
{ url: 'redis://redis-node-2:6379' },
|
|
258
|
-
{ url: 'redis://redis-node-3:6379' },
|
|
259
|
-
]),
|
|
260
|
-
});
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
The cluster client automatically handles:
|
|
264
|
-
- Topology discovery
|
|
265
|
-
- Command routing based on key hash slots
|
|
266
|
-
- Node failures and redirects (MOVED/ASK errors)
|
|
267
|
-
- High availability and horizontal scaling
|
|
268
|
-
|
|
269
|
-
**Other Options:**
|
|
270
|
-
- **Redis Sentinel** - Automatic failover (use with single-instance Redis client)
|
|
271
|
-
- **Dragonfly** - Drop-in Redis replacement with better performance (works with same client)
|
|
272
|
-
|
|
273
|
-
## License
|
|
274
|
-
|
|
275
|
-
MIT
|
|
7
|
+
**This is a preview release for internal testing. Do not use in production yet.**
|
|
276
8
|
|
|
9
|
+
This package is part of nauth-toolkit and is currently in early access/preview. Features and APIs may change between releases. For production use, please wait for the stable v1.0 release.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nauth-toolkit/storage-redis",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "Redis storage adapter for nauth-toolkit using the redis package (node-redis)",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"format:check": "prettier --check \"src/**/*.ts\""
|
|
15
15
|
},
|
|
16
16
|
"peerDependencies": {
|
|
17
|
-
"@nauth-toolkit/core": "^0.1.
|
|
17
|
+
"@nauth-toolkit/core": "^0.1.6",
|
|
18
18
|
"redis": "^4.6.0 || ^5.0.0"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
},
|
|
30
30
|
"publishConfig": {
|
|
31
31
|
"access": "public",
|
|
32
|
-
"tag": "
|
|
32
|
+
"tag": "latest"
|
|
33
33
|
},
|
|
34
34
|
"license": "UNLICENSED",
|
|
35
35
|
"keywords": [
|