passport-oauth2

repository·master·Indexed 20 days ago

https://github.com/jaredhanson/passport-oauth2

A general-purpose OAuth 2.0 authentication strategy for Passport.js, allowing developers to integrate OAuth 2.0 authentication into Node.js applications using Connect-style middleware like Express. It provides a base OAuth2Strategy for generic providers and can be sub-classed to create provider-specific strategies. Version 1.8.0 includes support for state management via SessionStore and PKCESessionStore, as well as specialized error classes including AuthorizationError, TokenError, and InternalOAuthError.

Tokens
3.2K
Snippets
11
Records
15
Agent score
70%

What's inside passport-oauth2

  1. When to use passport-oauth2 vs provider-specific strategies

    master

    The passport-oauth2 module provides generic OAuth 2.0 support.

    • Use provider-specific strategies (e.g., passport-google-oauth2) when available. These strategies reduce configuration overhead and handle provider-specific quirks automatically.
    • Use passport-oauth2 when you need to implement authentication against an OAuth 2.0 provider that does not have a dedicated Passport strategy.
    • Sub-classing: If you are building a new provider-specific strategy, you are encouraged to sub-class this OAuth2Strategy.
  2. Authenticate requests using OAuth 2.0

    master

    Use passport.authenticate('oauth2') as middleware in your routes to handle the OAuth 2.0 flow. This typically involves two routes: one to initiate the authentication process and a callback route to handle the response from the provider.

    When defining the callback route, you can provide options like failureRedirect to specify where the user should be sent if authentication fails.

    // Route to initiate authentication
    app.get('/auth/example',
      passport.authenticate('oauth2'));
    
    // Callback route after provider redirect
    app.get('/auth/example/callback',
      passport.authenticate('oauth2', { failureRedirect: '/login' }),
      function(req, res) {
        // Successful authentication, redirect home.
        res.redirect('/');
      });
  3. Use SessionStore for OAuth2 state management

    master

    When using the state option in OAuth2Strategy, passport-oauth2 requires a state store to generate and verify CSRF tokens. SessionStore is the built-in implementation that stores these tokens in req.session.

    Requirements:

    • You must have session support enabled in your application (e.g., using express-session middleware).
    • You must provide a key in the options to specify where the state should be stored in the session object.

    Error Handling: If req.session is missing, the store will throw an error: OAuth 2.0 authentication requires session support when using state. Did you forget to use express-session middleware?

    const SessionStore = require('passport-oauth2/lib/state/store');
    
    // When configuring your strategy:
    const options = {
      // ... other options
      stateStore: new SessionStore({ key: 'oauth2_state' })
    };
  4. Configure the OAuth2Strategy

    master

    To use the strategy, instantiate OAuth2Strategy with a configuration object and a verify callback.

    Configuration Options:

    • authorizationURL: The provider's OAuth 2.0 authorization endpoint.
    • tokenURL: The provider's OAuth 2.0 token endpoint.
    • clientID: Your application's client identifier.
    • clientSecret: Your application's client secret.
    • callbackURL: The URL where the provider will redirect the user after authorization.

    Verify Callback Signature: function(accessToken, refreshToken, profile, cb)

    • accessToken: The access token issued by the provider.
    • refreshToken: The refresh token (if provided).
    • profile: The profile information returned by the provider.
    • cb: A callback function used to pass an error and/or a user object to Passport.
    passport.use(new OAuth2Strategy({
        authorizationURL: 'https://www.example.com/oauth2/authorize',
        tokenURL: 'https://www.example.com/oauth2/token',
        clientID: EXAMPLE_CLIENT_ID,
        clientSecret: EXAMPLE_CLIENT_SECRET,
        callbackURL: "http://localhost:3000/auth/example/callback"
      },
      function(accessToken, refreshToken, profile, cb) {
        User.findOrCreate({ exampleId: profile.id }, function (err, user) {
          return cb(err, user);
        });
      }
    ));
  5. Configure SessionStore options

    master

    The SessionStore constructor accepts an options object to define how state is persisted in the user's session.

    OptionTypeDescription
    keyStringRequired. The key in the req.session object under which the OAuth2 state will be stored.

    If key is not provided, a TypeError is thrown: Session-based state store requires a session key.

    const store = new SessionStore({ key: 'my_custom_state_key' });
  6. Configure SessionStore for OAuth2 state management

    master

    When using the state option in OAuth2Strategy, you can provide a SessionStore to manage the CSRF protection state. The SessionStore generates a random state string, stores it in the user's session, and verifies it upon the user's return from the service provider.

    Requirements:

    • You must have session middleware (like express-session) configured in your application.
    • You must provide a key in the options object to specify where the state should be stored within req.session.
    const SessionStore = require('passport-oauth2/lib/state/session');
    
    // When initializing your strategy:
    const options = {
      key: 'oauth2_state' // The key used in req.session
    };
    
    const store = new SessionStore(options);
  7. Handle and debug OAuth errors with InternalOAuthError

    master

    When passport-oauth2 encounters an error from the underlying node-oauth library, it wraps it in an InternalOAuthError. This class is used to provide more descriptive error messages for debugging OAuth issues.

    When catching these errors, you can access the original error object via the oauthError property. The toString() method of this error class provides a formatted string that includes the error name, the custom message, and details from the underlying OAuth error (such as statusCode and data).

    // Example of how an InternalOAuthError might be structured
    // (Note: This is a conceptual representation of the error object you might catch)
    
    try {
      // ... OAuth logic that fails ...
    } catch (err) {
      if (err.name === 'InternalOAuthError') {
        console.error(err.toString());
        // Access the underlying error details
        console.error('Original error:', err.oauthError);
      }
    }
  8. Handle token endpoint errors with TokenError

    master

    When an error is received from an OAuth 2.0 token endpoint, passport-oauth2 may throw or return a TokenError. This error follows the structure defined in RFC 6749, section 5.2.

    When catching this error, you can inspect the following properties to determine the cause of the failure:

    • message: A human-readable description of the error.
    • code: An OAuth 2.0 error code (e.g., invalid_request, invalid_client). Defaults to 'invalid_request' if not provided.
    • uri: A URI explaining the error details.
    • status: The HTTP status code associated with the error. Defaults to 500 if not provided.
  9. Troubleshoot session errors in PKCE state storage

    master

    If you encounter an error stating OAuth 2.0 authentication requires session support when using state. Did you forget to use express-session middleware?, it means the PKCESessionStore is attempting to access req.session but it is undefined.

    To resolve this, ensure that you have session middleware (such as express-session) configured and applied to your application before the Passport middleware is invoked.

  10. Troubleshoot missing session support in OAuth2 state management

    master

    If you are using SessionStore and encounter errors, ensure that your application is correctly using session middleware. The SessionStore relies on req.session being present to function.

    Common Error Message: OAuth 2.0 authentication requires session support when using state. Did you forget to use express-session middleware?

  11. Import the passport-oauth2 Strategy and Error classes

    master

    The passport-oauth2 module exports the Strategy class as its primary export, and also provides named exports for specific error types used during the OAuth 2.0 flow. You can require the module directly to get the Strategy or use named properties to access the error classes for error handling.

    const OAuth2Strategy = require('passport-oauth2').Strategy;
    const { 
      AuthorizationError, 
      TokenError, 
      InternalOAuthError 
    } = require('passport-oauth2');