backend-passport-js
Authentication middleware for Express.js and Node.js applications. Use when building Express APIs that need JWT authentication, OAuth, or custom auth strategies. Provides 500+ authentication strategies. Choose Passport.js over Auth.js for Express backends, pure API servers, or when you need maximum control over auth flow.
Best use case
backend-passport-js is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Authentication middleware for Express.js and Node.js applications. Use when building Express APIs that need JWT authentication, OAuth, or custom auth strategies. Provides 500+ authentication strategies. Choose Passport.js over Auth.js for Express backends, pure API servers, or when you need maximum control over auth flow.
Teams using backend-passport-js should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/backend-passport-js/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How backend-passport-js Compares
| Feature / Agent | backend-passport-js | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Authentication middleware for Express.js and Node.js applications. Use when building Express APIs that need JWT authentication, OAuth, or custom auth strategies. Provides 500+ authentication strategies. Choose Passport.js over Auth.js for Express backends, pure API servers, or when you need maximum control over auth flow.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Passport.js (Express Authentication)
## Overview
Passport.js is the de-facto standard authentication middleware for Express.js. It uses a strategy pattern with 500+ available strategies for different auth mechanisms.
**Version**: passport@0.7.x, passport-jwt@4.x
**Use case**: Express.js applications, custom auth flows, pure APIs
**Key Benefit**: Maximum flexibility, works with any Express app, battle-tested in production.
## When to Use This Skill
✅ **Use Passport.js when:**
- Building Express.js REST APIs
- Need JWT-based authentication for APIs
- Want 500+ auth strategies available
- Require custom authentication logic
- Building microservices or pure backend APIs
- Not using Next.js
❌ **Use Auth.js instead when:**
- Building Next.js applications
- Want minimal configuration
- Need quick OAuth setup
- Want serverless/Edge support
---
## Quick Start
### Installation
```bash
npm install passport passport-jwt jsonwebtoken
npm install -D @types/passport @types/passport-jwt @types/jsonwebtoken
```
### JWT Strategy Setup
```typescript
// src/strategies/jwt.strategy.ts
import passport from 'passport';
import { Strategy as JwtStrategy, ExtractJwt } from 'passport-jwt';
import { prisma } from '../lib/prisma';
const options = {
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: process.env.JWT_SECRET!,
};
passport.use(new JwtStrategy(options, async (payload, done) => {
try {
const user = await prisma.user.findUnique({
where: { id: payload.sub }
});
if (!user) {
return done(null, false);
}
return done(null, user);
} catch (error) {
return done(error, false);
}
}));
export default passport;
```
---
## Express Integration
### Complete Setup
```typescript
// src/app.ts
import express from 'express';
import passport from 'passport';
import jwt from 'jsonwebtoken';
import { hash, verify } from 'argon2';
import './strategies/jwt.strategy';
import { prisma } from './lib/prisma';
const app = express();
app.use(express.json());
app.use(passport.initialize());
// Register
app.post('/auth/register', async (req, res) => {
const { email, password, name } = req.body;
const hashedPassword = await hash(password);
const user = await prisma.user.create({
data: { email, password: hashedPassword, name },
});
res.status(201).json({ id: user.id, email: user.email });
});
// Login
app.post('/auth/login', async (req, res) => {
const { email, password } = req.body;
const user = await prisma.user.findUnique({ where: { email } });
if (!user || !user.password) {
return res.status(401).json({ message: 'Invalid credentials' });
}
const valid = await verify(user.password, password);
if (!valid) {
return res.status(401).json({ message: 'Invalid credentials' });
}
const accessToken = jwt.sign(
{ sub: user.id, email: user.email, role: user.role },
process.env.JWT_SECRET!,
{ expiresIn: '15m' }
);
const refreshToken = jwt.sign(
{ sub: user.id },
process.env.JWT_REFRESH_SECRET!,
{ expiresIn: '7d' }
);
res.json({ accessToken, refreshToken });
});
// Protected route
app.get('/api/profile',
passport.authenticate('jwt', { session: false }),
(req, res) => {
res.json(req.user);
}
);
// Refresh token
app.post('/auth/refresh', async (req, res) => {
const { refreshToken } = req.body;
try {
const payload = jwt.verify(refreshToken, process.env.JWT_REFRESH_SECRET!) as { sub: string };
const user = await prisma.user.findUnique({ where: { id: payload.sub } });
if (!user) {
return res.status(401).json({ message: 'Invalid token' });
}
const accessToken = jwt.sign(
{ sub: user.id, email: user.email, role: user.role },
process.env.JWT_SECRET!,
{ expiresIn: '15m' }
);
res.json({ accessToken });
} catch {
res.status(401).json({ message: 'Invalid token' });
}
});
app.listen(3000);
```
---
## Middleware Helpers
### Role-Based Authorization
```typescript
// src/middleware/auth.middleware.ts
import { Request, Response, NextFunction } from 'express';
import passport from 'passport';
// Authenticate and attach user
export const authenticate = passport.authenticate('jwt', { session: false });
// Check specific role
export function requireRole(...roles: string[]) {
return (req: Request, res: Response, next: NextFunction) => {
const user = req.user as { role: string } | undefined;
if (!user || !roles.includes(user.role)) {
return res.status(403).json({ message: 'Forbidden' });
}
next();
};
}
// Usage:
app.get('/admin/users',
authenticate,
requireRole('admin'),
(req, res) => { /* ... */ }
);
```
### Optional Authentication
```typescript
export function optionalAuth(req: Request, res: Response, next: NextFunction) {
passport.authenticate('jwt', { session: false }, (err, user) => {
if (user) req.user = user;
next();
})(req, res, next);
}
// Route works with or without auth
app.get('/api/posts', optionalAuth, (req, res) => {
const userId = (req.user as { id: string })?.id;
// Show public posts, or personalized if logged in
});
```
---
## Integration with tRPC (Express)
```typescript
// src/server/context.ts
import { CreateExpressContextOptions } from '@trpc/server/adapters/express';
import { prisma } from '../lib/prisma';
export const createContext = ({ req }: CreateExpressContextOptions) => ({
user: req.user, // Populated by Passport middleware
prisma,
});
export type Context = ReturnType<typeof createContext>;
```
```typescript
// src/server/index.ts
import { createExpressMiddleware } from '@trpc/server/adapters/express';
import passport from 'passport';
// Apply Passport to all /trpc routes
app.use('/trpc',
passport.authenticate('jwt', { session: false, failWithError: false }),
createExpressMiddleware({
router: appRouter,
createContext,
})
);
```
---
## JWT Token Structure
```typescript
// Access token payload
interface AccessTokenPayload {
sub: string; // User ID
email: string;
role: string;
iat: number; // Issued at
exp: number; // Expiration
}
// Generate tokens
function generateTokens(user: User) {
const accessToken = jwt.sign(
{ sub: user.id, email: user.email, role: user.role },
process.env.JWT_SECRET!,
{ expiresIn: '15m' }
);
const refreshToken = jwt.sign(
{ sub: user.id },
process.env.JWT_REFRESH_SECRET!,
{ expiresIn: '7d' }
);
return { accessToken, refreshToken };
}
```
---
## Type Definitions
```typescript
// src/types/express.d.ts
import { User } from '@prisma/client';
declare global {
namespace Express {
interface User {
id: string;
email: string;
role: string;
}
}
}
```
---
## Environment Variables
```env
JWT_SECRET=your-access-token-secret-min-32-chars
JWT_REFRESH_SECRET=your-refresh-token-secret-min-32-chars
```
---
## Rules
### Do ✅
- Use `session: false` for stateless JWT auth
- Hash passwords with argon2 or bcrypt
- Use short-lived access tokens (15min)
- Use refresh tokens for long sessions
- Store refresh tokens securely (httpOnly cookie)
- Validate JWT on every request
### Avoid ❌
- Storing sensitive data in JWT payload
- Using long-lived access tokens
- Storing tokens in localStorage (XSS risk)
- Using weak secrets
- Skipping password hashing
---
## Common Strategies
| Strategy | Package | Use Case |
|----------|---------|----------|
| JWT | `passport-jwt` | API authentication |
| Local | `passport-local` | Username/password |
| OAuth2 | `passport-oauth2` | Generic OAuth |
| Google | `passport-google-oauth20` | Google login |
| GitHub | `passport-github2` | GitHub login |
---
## Auth.js vs Passport.js Decision Tree
| Scenario | Recommendation |
|----------|---------------|
| Next.js App Router | **Auth.js** |
| Express.js API | **Passport.js** |
| Quick OAuth setup | **Auth.js** |
| Custom auth logic | **Passport.js** |
| Serverless/Edge | **Auth.js** |
| Multiple strategies | **Passport.js** |
| Pure JWT API | **Passport.js** |
---
## Troubleshooting
```yaml
"401 on every request":
→ Check Authorization header format: "Bearer <token>"
→ Verify JWT_SECRET matches between sign and verify
→ Check token expiration
"req.user is undefined":
→ Ensure passport.initialize() is called
→ Check authenticate middleware is applied
→ Verify strategy name matches
"CORS issues with auth":
→ Set credentials: true in CORS config
→ Include origin whitelist
→ Allow Authorization header
"Token not refreshing":
→ Check refresh token secret is different
→ Verify refresh token hasn't expired
→ Store refresh token in httpOnly cookie
```
---
## File Structure
```
src/
├── strategies/
│ └── jwt.strategy.ts # JWT strategy config
├── middleware/
│ └── auth.middleware.ts # Auth helpers
├── routes/
│ └── auth.routes.ts # Auth endpoints
└── types/
└── express.d.ts # Type extensions
```
## References
- https://passportjs.org — Official documentation
- https://www.npmjs.com/package/passport-jwt — JWT strategy
- http://www.passportjs.org/packages/ — All strategiesRelated Skills
backendless-automation
Automate Backendless tasks via Rube MCP (Composio). Always search tools first for current schemas.
backend-ultimate
Ultimate 25+ years expert-level backend skill covering FastAPI, Express, Node.js, Next.js with TypeScript. Includes ALL databases (PostgreSQL, MongoDB, Redis, Elasticsearch), ALL features (REST, GraphQL, WebSockets, gRPC, Message Queues), comprehensive security hardening (XSS, CSRF, SQL injection, authentication, authorization, rate limiting), complete performance optimization (caching, database tuning, load balancing), ALL deployment strategies (Docker, Kubernetes, CI/CD), advanced patterns (microservices, event-driven, saga, CQRS), ALL use cases (e-commerce, SaaS, real-time, high-traffic), complete testing (unit, integration, E2E, load, security). Route protection, middleware, authentication implementation in PERFECTION. Use for ANY backend system requiring enterprise-grade security, performance, scalability, and architectural excellence.
backend-testing
Write comprehensive backend tests including unit tests, integration tests, and API tests. Use when testing REST APIs, database operations, authentication flows, or business logic. Handles Jest, Pytest, Mocha, testing strategies, mocking, and test coverage.
backend-skills
Master Node.js, Express, PHP, Laravel, Java, Spring Boot, API design, and database integration. Build scalable APIs and server applications.
backend-skill
Design and implement backend functionality including route generation, request/response handling, and database connectivity.
backend-service-patterns
Architect scalable backend services using layered architecture, dependency injection, middleware patterns, service classes, and separation of concerns. Use when building API services, implementing business logic layers, creating service classes, setting up middleware chains, implementing dependency injection, designing controller-service-repository patterns, handling cross-cutting concerns, creating domain models, implementing CQRS patterns, or establishing backend architecture standards.
backend-scaffold
Generate production-ready backend code with routes, data models, service layers, and validation. Use when scaffolding backend from specs.
Backend Queries
Write secure, performant, and optimized database queries using parameterized queries, eager loading, proper indexing, and transaction management. Use this skill when writing database queries in controllers, repositories, services, or model methods, when using query builders or ORM methods, when implementing filtering/sorting/pagination logic, when optimizing N+1 query problems with eager loading, when working with joins and complex queries, when implementing query caching, or when wrapping related operations in database transactions.
Backend Python Expert
专注于 Python 后端开发,涵盖 FastAPI、异步编程和性能优化。
backend-python-developer
Use this agent when you need expert backend development work with Python, including API design, database integration, authentication, testing, or any Python backend-focused development tasks.
backend-patterns
Backend patterns for ORPC routers, Drizzle schemas, and server-side code. Use when creating API endpoints, database tables, or services.
backend-nodejs
Node.js/TypeScript backend expert. Handles Express/Fastify API routes, TypeScript strict mode, Prisma ORM, Zod validation, error handling, configuration management. Use when project is Node.js backend (package.json + TypeScript server).