{"id":14800,"library":"passport-strategy","title":"Passport Strategy Base Class","description":"The `passport-strategy` package provides an abstract `Strategy` class that serves as the foundational interface for implementing concrete authentication strategies within the Passport.js ecosystem. It defines the core API, including the `authenticate()` method and helper functions like `success()`, `fail()`, `redirect()`, `pass()`, and `error()`, which custom strategies must implement or utilize to manage the authentication flow. While the core `passport` package is actively maintained (latest version ~0.7.0 as of late 2023), the `passport-strategy` package itself, version 1.0.0, has not seen updates since 2013, making it a very stable but effectively unmaintained base. Developers primarily interact with this module by extending its `Strategy` class to create custom authentication logic (e.g., `passport-local`, `passport-github`). Its key differentiator is its role as the common contract for all Passport strategies, enabling a highly modular and extensible authentication system for Node.js applications.","status":"maintenance","version":"1.0.0","language":"javascript","source_language":"en","source_url":"git://github.com/jaredhanson/passport-strategy","tags":["javascript","passport","strategy"],"install":[{"cmd":"npm install passport-strategy","lang":"bash","label":"npm"},{"cmd":"yarn add passport-strategy","lang":"bash","label":"yarn"},{"cmd":"pnpm add passport-strategy","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"While the package is primarily CommonJS, modern TypeScript/ESM projects often use `import` syntax, with bundlers handling the interop. The constructor is the default export.","wrong":"const Strategy = require('passport-strategy').Strategy;","symbol":"Strategy","correct":"import { Strategy } from 'passport-strategy';"},{"note":"In CommonJS, the `Strategy` constructor is the direct module.exports, not a named export. Many examples mistakenly try to destructure it.","wrong":"const { Strategy } = require('passport-strategy');","symbol":"Strategy (CommonJS)","correct":"const Strategy = require('passport-strategy');"}],"quickstart":{"code":"const util = require('util');\nconst Strategy = require('passport-strategy');\n\n/**\n * A simple custom strategy extending passport-strategy.\n * This example demonstrates a basic 'always success' strategy.\n */\nfunction CustomAlwaysSuccessStrategy(options) {\n  Strategy.call(this);\n  this.name = 'custom-always-success';\n  this._options = options || {};\n}\n\nutil.inherits(CustomAlwaysSuccessStrategy, Strategy);\n\n/**\n * The authenticate method must be overridden by subclasses.\n * It performs the actual authentication logic.\n */\nCustomAlwaysSuccessStrategy.prototype.authenticate = function(req, options) {\n  // In a real strategy, you would parse credentials from req,\n  // interact with a database, call an external API, etc.\n  // For this example, we simply succeed immediately with a dummy user.\n  const user = { id: '123', name: 'Test User' };\n  const info = { message: 'Authentication successful with custom strategy.' };\n\n  // Call one of the action functions provided by the base Strategy class.\n  // This indicates the outcome of the authentication attempt.\n  this.success(user, info);\n\n  // Other possible outcomes:\n  // this.fail({ message: 'Invalid credentials' }, 401);\n  // this.redirect('/login', 302);\n  // this.pass(); // defer to next strategy\n  // this.error(new Error('Something went wrong'));\n};\n\n// Example usage with Passport.js (requires 'passport' package)\nconst passport = require('passport');\npassport.use(new CustomAlwaysSuccessStrategy());\n\n// To test, imagine an Express route:\n// app.get('/auth/custom', passport.authenticate('custom-always-success', { session: false }), (req, res) => {\n//   res.json({ message: 'Logged in!', user: req.user });\n// });\n\n// For demonstration, let's manually 'authenticate' (without Express context)\n// In a real app, this would be handled by Passport middleware.\nconst dummyReq = {}; // Simulate an Express request object\nconst strategyInstance = new CustomAlwaysSuccessStrategy();\nstrategyInstance.authenticate(dummyReq, {}, (err, user, info) => {\n  if (user) {\n    console.log('Authentication successful:', user, info);\n  } else {\n    console.error('Authentication failed:', err || info);\n  }\n});\n","lang":"javascript","description":"This quickstart demonstrates how to define a custom authentication strategy by subclassing the `Strategy` abstract class, overriding its `authenticate` method, and registering it with Passport.js. It shows a simplified 'always success' scenario and how the base class's success method is called."},"warnings":[{"fix":"Consider using newer alternatives or explicitly reviewing the base `Strategy` implementation within the currently maintained `passport` package itself or derived strategies. For new projects, ensure compatibility with the `passport` version you are using. There is also `@passport-next/passport-strategy` (v1.1.0, published 2018) which offers a slightly newer base.","message":"The `passport-strategy` package (v1.0.0) is very old, last published in 2013, and has not received updates in over a decade. While still functional as a base class, developers should be aware that it might not align with the latest Node.js features, security best practices, or modern JavaScript syntax (e.g., pure ESM).","severity":"breaking","affected_versions":"1.0.0"},{"fix":"For CommonJS, use `const Strategy = require('passport-strategy');` to correctly import the constructor. For ESM/TypeScript, `import Strategy from 'passport-strategy';` or `import { Strategy } from 'passport-strategy';` might be transpiled to work, but direct CommonJS interoperability should use the default import pattern.","message":"`passport-strategy` exports the `Strategy` constructor directly as `module.exports`, not as a named export. Attempting `const { Strategy } = require('passport-strategy');` in CommonJS environments will result in `undefined` for `Strategy`.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Always extend `Strategy` and provide your own `authenticate` method in the subclass. For example: `class CustomStrategy extends Strategy { authenticate(req, options) { /* ... */ } }` or `util.inherits(CustomStrategy, Strategy); CustomStrategy.prototype.authenticate = function(...) { /* ... */ };`.","message":"The `Strategy` class is abstract and *must* be subclassed. Instantiating `new Strategy()` directly and calling `authenticate()` without overriding it will result in an error or unexpected behavior, as the abstract `authenticate` method is not implemented in the base class.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Ensure `passport` and `express-session` (if using sessions) are installed and correctly configured in your application. Register your custom strategy using `passport.use(new MyStrategy());` and set up session serialization/deserialization.","message":"This package only provides the base class. To use custom strategies within an application, you must also install and configure the main `passport` package, including its middleware (`passport.initialize()` and `passport.session()`) and `serializeUser`/`deserializeUser` functions for session management.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"In CommonJS, ensure you use `const Strategy = require('passport-strategy');`. In ESM/TypeScript, ensure your transpilation handles `module.exports` correctly, often `import Strategy from 'passport-strategy';` is needed, or potentially `import { Strategy } from 'passport-strategy';` if tooling assumes named export behavior.","cause":"Attempting to use `new Strategy()` after incorrectly importing it as a named export in CommonJS, or a general incorrect import path.","error":"TypeError: Strategy is not a constructor"},{"fix":"Create a subclass that extends `Strategy` and provides its own `authenticate(req, options)` method with your authentication logic. `class MyStrategy extends Strategy { authenticate(req, options) { /* ... */ } }`","cause":"You are attempting to use the abstract `Strategy` class directly without extending it and implementing your own `authenticate` method.","error":"TypeError: Strategy#authenticate must be overridden by subclass"},{"fix":"Verify that `app.use(passport.initialize());` and `app.use(passport.session());` (if using sessions) are correctly placed before any routes that require authentication. Also, ensure `passport.serializeUser` and `passport.deserializeUser` are implemented to manage user sessions.","cause":"This typically indicates that `passport.initialize()` and/or `passport.session()` middleware are not correctly configured, or `passport.serializeUser`/`deserializeUser` are missing or misconfigured, preventing the authenticated user from being attached to the request.","error":"TypeError: Cannot read properties of undefined (reading 'user') on req.user after authentication"}],"ecosystem":"npm"}