0
# Passport OAuth2
1
2
General-purpose OAuth 2.0 authentication strategy for Passport.js that enables developers to implement OAuth 2.0-based authentication in Node.js applications. It serves as a foundation for building provider-specific OAuth 2.0 strategies and integrates seamlessly with Connect-style middleware frameworks like Express.
3
4
## Package Information
5
6
- **Package Name**: passport-oauth2
7
- **Package Type**: npm
8
- **Language**: JavaScript
9
- **Installation**: `npm install passport-oauth2`
10
11
## Core Imports
12
13
```javascript
14
// Main import (default export is the Strategy constructor)
15
const OAuth2Strategy = require('passport-oauth2');
16
17
// Named imports for strategy and error classes
18
const { Strategy, AuthorizationError, TokenError, InternalOAuthError } = require('passport-oauth2');
19
```
20
21
ES Modules:
22
```javascript
23
import OAuth2Strategy from 'passport-oauth2';
24
// Or with named imports
25
import { Strategy, AuthorizationError, TokenError, InternalOAuthError } from 'passport-oauth2';
26
```
27
28
## Basic Usage
29
30
```javascript
31
const passport = require('passport');
32
const OAuth2Strategy = require('passport-oauth2');
33
34
// Configure the strategy
35
passport.use(new OAuth2Strategy({
36
authorizationURL: 'https://www.example.com/oauth2/authorize',
37
tokenURL: 'https://www.example.com/oauth2/token',
38
clientID: 'your-client-id',
39
clientSecret: 'your-client-secret',
40
callbackURL: "http://localhost:3000/auth/example/callback"
41
},
42
function(accessToken, refreshToken, profile, done) {
43
// Find or create user based on profile
44
User.findOrCreate({ exampleId: profile.id }, function (err, user) {
45
return done(err, user);
46
});
47
}
48
));
49
50
// Use in Express routes
51
app.get('/auth/example', passport.authenticate('oauth2'));
52
53
app.get('/auth/example/callback',
54
passport.authenticate('oauth2', { failureRedirect: '/login' }),
55
function(req, res) {
56
res.redirect('/');
57
});
58
```
59
60
## Architecture
61
62
Passport OAuth2 is built around several key components:
63
64
- **OAuth2Strategy**: Core strategy class that extends passport.Strategy and handles the OAuth 2.0 flow
65
- **Error Classes**: Specialized error types for different OAuth 2.0 failure scenarios
66
- **State Management**: Multiple state store implementations for CSRF protection and PKCE support
67
- **Extensibility**: Virtual methods that can be overridden for provider-specific behavior
68
- **Verification Callback**: User-defined function that handles user creation/authentication after successful OAuth flow
69
70
## Capabilities
71
72
### OAuth2 Strategy
73
74
Core OAuth 2.0 authentication strategy that handles authorization flow, token exchange, and user profile retrieval.
75
76
```javascript { .api }
77
/**
78
* Creates an OAuth2Strategy instance
79
* @param options - Configuration options for OAuth 2.0 provider
80
* @param verify - Callback function for user verification
81
*/
82
function OAuth2Strategy(options, verify);
83
84
interface OAuth2StrategyOptions {
85
authorizationURL: string; // Required: Authorization endpoint URL
86
tokenURL: string; // Required: Token endpoint URL
87
clientID: string; // Required: OAuth client identifier
88
clientSecret?: string; // Client secret for authentication
89
callbackURL?: string; // Redirect URI after authorization
90
scope?: string | string[]; // Requested access scope
91
scopeSeparator?: string; // Scope separator (default: ' ')
92
state?: boolean; // Enable CSRF protection
93
store?: boolean | object; // State store configuration
94
sessionKey?: string; // Session key for state storage
95
pkce?: boolean | string; // Enable PKCE ('S256', 'plain', or boolean)
96
proxy?: boolean; // Trust proxy headers
97
passReqToCallback?: boolean; // Pass request to verify callback
98
skipUserProfile?: boolean | SkipUserProfileFunction; // Skip profile retrieval
99
customHeaders?: object; // Custom headers for OAuth requests
100
}
101
102
/**
103
* Function to conditionally skip user profile loading
104
*/
105
type SkipUserProfileFunction = (
106
accessToken: string,
107
done: (err?: Error, skip?: boolean) => void
108
) => void;
109
110
/**
111
* Verify callback signatures
112
*/
113
type VerifyCallback = (
114
accessToken: string,
115
refreshToken: string,
116
profile: object,
117
done: (err?: Error, user?: any, info?: any) => void
118
) => void;
119
120
type VerifyCallbackWithParams = (
121
accessToken: string,
122
refreshToken: string,
123
params: object,
124
profile: object,
125
done: (err?: Error, user?: any, info?: any) => void
126
) => void;
127
128
type VerifyCallbackWithRequest = (
129
req: object,
130
accessToken: string,
131
refreshToken: string,
132
profile: object,
133
done: (err?: Error, user?: any, info?: any) => void
134
) => void;
135
136
type VerifyCallbackWithRequestAndParams = (
137
req: object,
138
accessToken: string,
139
refreshToken: string,
140
params: object,
141
profile: object,
142
done: (err?: Error, user?: any, info?: any) => void
143
) => void;
144
```
145
146
### Strategy Methods
147
148
Core methods available on OAuth2Strategy instances for authentication flow control and customization.
149
150
```javascript { .api }
151
/**
152
* Main authentication method that handles OAuth 2.0 flow
153
* @param req - HTTP request object
154
* @param options - Authentication options
155
*/
156
OAuth2Strategy.prototype.authenticate = function(req, options);
157
158
/**
159
* Retrieve user profile from service provider (virtual method)
160
* @param accessToken - OAuth access token
161
* @param done - Callback function
162
*/
163
OAuth2Strategy.prototype.userProfile = function(accessToken, done);
164
165
/**
166
* Return extra parameters for authorization request (virtual method)
167
* @param options - Options object
168
* @returns Object with additional parameters
169
*/
170
OAuth2Strategy.prototype.authorizationParams = function(options);
171
172
/**
173
* Return extra parameters for token request (virtual method)
174
* @param options - Options object
175
* @returns Object with additional parameters
176
*/
177
OAuth2Strategy.prototype.tokenParams = function(options);
178
179
/**
180
* Parse error response from OAuth 2.0 endpoint (virtual method)
181
* @param body - Response body string
182
* @param status - HTTP status code
183
* @returns Error object or null
184
*/
185
OAuth2Strategy.prototype.parseErrorResponse = function(body, status);
186
187
/**
188
* Load user profile with conditional skipping (internal method)
189
* @param accessToken - OAuth access token
190
* @param done - Callback function
191
*/
192
OAuth2Strategy.prototype._loadUserProfile = function(accessToken, done);
193
194
/**
195
* Create OAuth error wrapper with provider-specific parsing (internal method)
196
* Attempts to parse error response, falls back to InternalOAuthError
197
* @param message - Error message
198
* @param err - Original error with statusCode and data
199
* @returns TokenError from parseErrorResponse or InternalOAuthError
200
*/
201
OAuth2Strategy.prototype._createOAuthError = function(message, err);
202
```
203
204
### Error Handling
205
206
Specialized error classes for different OAuth 2.0 failure scenarios with proper error codes and HTTP status mapping.
207
208
```javascript { .api }
209
/**
210
* Authorization error representing OAuth authorization failures
211
* @param message - Error message
212
* @param code - OAuth error code
213
* @param uri - Error URI reference
214
* @param status - HTTP status code
215
*/
216
function AuthorizationError(message, code, uri, status);
217
218
/**
219
* Token error representing OAuth token endpoint failures
220
* @param message - Error message
221
* @param code - OAuth error code (default: 'invalid_request')
222
* @param uri - Error URI reference
223
* @param status - HTTP status code (default: 500)
224
*/
225
function TokenError(message, code, uri, status);
226
227
/**
228
* Internal OAuth error wrapping node-oauth errors
229
* @param message - Error message
230
* @param err - Original error object
231
*/
232
function InternalOAuthError(message, err);
233
```
234
235
[Error Handling](./error-handling.md)
236
237
### State Management
238
239
State store implementations for CSRF protection and PKCE support with multiple storage backends.
240
241
```javascript { .api }
242
/**
243
* Full session-based state store with metadata support (from lib/state/store)
244
* @param options - Configuration options
245
*/
246
function StateStore(options);
247
248
/**
249
* Simple session-based nonce store for basic CSRF protection (from lib/state/session)
250
* @param options - Configuration options
251
*/
252
function SessionStore(options);
253
254
/**
255
* PKCE-enabled session state store with code verifier support (from lib/state/pkcesession)
256
* @param options - Configuration options
257
*/
258
function PKCESessionStore(options);
259
260
/**
261
* No-op state store that performs no validation (from lib/state/null)
262
* @param options - Configuration options
263
*/
264
function NullStore(options);
265
266
interface StateStoreOptions {
267
key: string; // Required: Session key for storing state
268
}
269
```
270
271
[State Management](./state-management.md)
272
273
### Utility Functions
274
275
Internal utility functions for URL reconstruction and object merging used by the OAuth2 flow.
276
277
```javascript { .api }
278
/**
279
* Reconstructs the original URL of the request with protocol and host
280
* @param req - HTTP request object
281
* @param options - Configuration options for proxy handling
282
* @returns Complete URL string
283
*/
284
function originalURL(req, options);
285
286
/**
287
* Merge utility from utils-merge package
288
* @param destination - Target object
289
* @param source - Source object to merge
290
* @returns Merged object
291
*/
292
function merge(destination, source);
293
294
interface OriginalURLOptions {
295
proxy?: boolean; // Trust proxy headers for protocol detection
296
}
297
```
298
299
## Types
300
301
```javascript { .api }
302
/**
303
* Base Strategy class from passport-strategy
304
*/
305
interface Strategy {
306
name: string;
307
authenticate(req: any, options?: any): void;
308
success(user: any, info?: any): void;
309
fail(challenge?: any, status?: number): void;
310
redirect(url: string, status?: number): void;
311
pass(): void;
312
error(err: Error): void;
313
}
314
315
/**
316
* OAuth2Strategy class extending Strategy
317
*/
318
interface OAuth2Strategy extends Strategy {
319
name: 'oauth2';
320
_verify: VerifyCallback;
321
_oauth2: OAuth2Client;
322
_callbackURL?: string;
323
_scope?: string | string[];
324
_scopeSeparator: string;
325
_pkceMethod?: string;
326
_key: string;
327
_stateStore: StateStore;
328
_trustProxy?: boolean;
329
_passReqToCallback?: boolean;
330
_skipUserProfile: boolean | SkipUserProfileFunction;
331
}
332
333
/**
334
* OAuth2 client from node-oauth package
335
*/
336
interface OAuth2Client {
337
getOAuthAccessToken(code: string, params: any, callback: (err: any, accessToken?: string, refreshToken?: string, params?: any) => void): void;
338
_authorizeUrl: string;
339
_accessTokenUrl: string;
340
_clientId: string;
341
_clientSecret: string;
342
}
343
344
/**
345
* HTTP request object interface
346
*/
347
interface Request {
348
query?: { [key: string]: any };
349
body?: { [key: string]: any };
350
session?: { [key: string]: any };
351
app?: any;
352
headers?: { [key: string]: string };
353
connection?: { encrypted?: boolean };
354
url?: string;
355
}
356
357
/**
358
* State store interface
359
*/
360
interface StateStore {
361
store(req: Request, ...args: any[]): void;
362
verify(req: Request, providedState: string, callback: Function): void;
363
}
364
365
/**
366
* Error classes
367
*/
368
interface AuthorizationError extends Error {
369
name: 'AuthorizationError';
370
code: string;
371
uri?: string;
372
status: number;
373
}
374
375
interface TokenError extends Error {
376
name: 'TokenError';
377
code: string;
378
uri?: string;
379
status: number;
380
}
381
382
interface InternalOAuthError extends Error {
383
name: 'InternalOAuthError';
384
oauthError: any;
385
toString(): string;
386
}
387
```