Skip to content
Back to skills

1934 Auth Setup 45000180

ASecurity

Generate authentication boilerplate with JWT, OAuth, and session support

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
securitytypescriptgobashexpressfastapigitapibackend

Works with

  • cli
  • api

Security analysis

A100/100

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 1934-auth-setup_45000180 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 1934 Auth Setup 45000180?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 1934 Auth Setup 45000180
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-1934-auth-setup-45000180/badge)](https://www.skillsdirectory.com/skills/tools-only-1934-auth-setup-45000180)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
---
name: auth-setup
description: >
  Generate authentication boilerplate with JWT, OAuth, and session support
shortcut: as
category: backend
difficulty: intermediate
estimated_time: 5-10 minutes
---
# Auth Setup

Generates complete authentication boilerplate including JWT, OAuth (Google/GitHub), session management, and password reset flows.

## What This Command Does

**Generated Auth System:**
-  JWT authentication with refresh tokens
-  OAuth2 (Google, GitHub, Facebook)
-  Password hashing (bcrypt)
-  Email verification
-  Password reset flow
-  Session management
-  Rate limiting on auth endpoints
-  Authentication middleware

**Output:** Complete authentication system ready for production

**Time:** 5-10 minutes

---

## Usage

```bash
# Generate full auth system
/auth-setup jwt

# Shortcut
/as oauth --providers google,github

# With specific features
/as jwt --features email-verification,password-reset,2fa
```

---

## Example Output

### **JWT Authentication**

**auth.service.ts:**
```typescript
import bcrypt from 'bcrypt'
import jwt from 'jsonwebtoken'
import { User } from './models/User'

export class AuthService {
  async register(email: string, password: string, name: string) {
    // Check if user exists
    const existing = await User.findOne({ email })
    if (existing) {
      throw new Error('Email already registered')
    }

    // Hash password
    const hashedPassword = await bcrypt.hash(password, 12)

    // Create user
    const user = await User.create({
      email,
      password: hashedPassword,
      name,
      emailVerified: false
    })

    // Generate verification token
    const verificationToken = this.generateToken({ userId: user.id, type: 'verify' }, '24h')

    // Send verification email (implement sendEmail)
    await this.sendVerificationEmail(email, verificationToken)

    // Generate auth tokens
    const accessToken = this.generateAccessToken(user)
    const refreshToken = this.generateRefreshToken(user)

    return {
      user: { id: user.id, email: user.email, name: user.name },
      accessToken,
      refreshToken
    }
  }

  async login(email: string, password: string) {
    const user = await User.findOne({ email })
    if (!user) {
      throw new Error('Invalid credentials')
    }

    const validPassword = await bcrypt.compare(password, user.password)
    if (!validPassword) {
      throw new Error('Invalid credentials')
    }

    if (!user.emailVerified) {
      throw new Error('Please verify your email')
    }

    const accessToken = this.generateAccessToken(user)
    const refreshToken = this.generateRefreshToken(user)

    return {
      user: { id: user.id, email: user.email, name: user.name },
      accessToken,
      refreshToken
    }
  }

  async refreshToken(refreshToken: string) {
    try {
      const decoded = jwt.verify(refreshToken, process.env.JWT_REFRESH_SECRET!) as any

      const user = await User.findById(decoded.userId)
      if (!user) {
        throw new Error('User not found')
      }

      const accessToken = this.generateAccessToken(user)
      return { accessToken }
    } catch (error) {
      throw new Error('Invalid refresh token')
    }
  }

  async verifyEmail(token: string) {
    const decoded = jwt.verify(token, process.env.JWT_SECRET!) as any

    if (decoded.type !== 'verify') {
      throw new Error('Invalid token type')
    }

    await User.findByIdAndUpdate(decoded.userId, { emailVerified: true })
    return { message: 'Email verified successfully' }
  }

  async requestPasswordReset(email: string) {
    const user = await User.findOne({ email })
    if (!user) {
      // Don't reveal if user exists
      return { message: 'If email exists, reset link sent' }
    }

    const resetToken = this.generateToken({ userId: user.id, type: 'reset' }, '1h')
    await this.sendPasswordResetEmail(email, resetToken)

    return { message: 'If email exists, reset link sent' }
  }

  async resetPassword(token: string, newPassword: string) {
    const decoded = jwt.verify(token, process.env.JWT_SECRET!) as any

    if (decoded.type !== 'reset') {
      throw new Error('Invalid token type')
    }

    const hashedPassword = await bcrypt.hash(newPassword, 12)
    await User.findByIdAndUpdate(decoded.userId, { password: hashedPassword })

    return { message: 'Password reset successfully' }
  }

  private generateAccessToken(user: any) {
    return jwt.sign(
      { userId: user.id, email: user.email },
      process.env.JWT_SECRET!,
      { expiresIn: '15m' }
    )
  }

  private generateRefreshToken(user: any) {
    return jwt.sign(
      { userId: user.id },
      process.env.JWT_REFRESH_SECRET!,
      { expiresIn: '7d' }
    )
  }

  private generateToken(payload: any, expiresIn: string) {
    return jwt.sign(payload, process.env.JWT_SECRET!, { expiresIn })
  }

  private async sendVerificationEmail(email: string, token: string) {
    // Implement with SendGrid, Resend, etc.
  }

  private async sendPasswordResetEmail(email: string, token: string) {
    // Implement with SendGrid, Resend, etc.
  }
}
```

### **OAuth2 Setup (Google)**

**oauth.controller.ts:**
```typescript
import { OAuth2Client } from 'google-auth-library'

const googleClient = new OAuth2Client(
  process.env.GOOGLE_CLIENT_ID,
  process.env.GOOGLE_CLIENT_SECRET,
  process.env.GOOGLE_REDIRECT_URI
)

export class OAuthController {
  async googleLogin(req: Request, res: Response) {
    const authUrl = googleClient.generateAuthUrl({
      access_type: 'offline',
      scope: ['profile', 'email']
    })

    res.redirect(authUrl)
  }

  async googleCallback(req: Request, res: Response) {
    const { code } = req.query

    const { tokens } = await googleClient.getToken(code as string)
    googleClient.setCredentials(tokens)

    const ticket = await googleClient.verifyIdToken({
      idToken: tokens.id_token!,
      audience: process.env.GOOGLE_CLIENT_ID
    })

    const payload = ticket.getPayload()
    if (!payload) {
      throw new Error('Invalid token')
    }

    // Find or create user
    let user = await User.findOne({ email: payload.email })

    if (!user) {
      user = await User.create({
        email: payload.email,
        name: payload.name,
        avatar: payload.picture,
        emailVerified: true,
        provider: 'google',
        providerId: payload.sub
      })
    }

    // Generate tokens
    const accessToken = generateAccessToken(user)
    const refreshToken = generateRefreshToken(user)

    // Redirect with tokens
    res.redirect(`/auth/success?token=${accessToken}&refresh=${refreshToken}`)
  }
}
```

### **Authentication Middleware**

**auth.middleware.ts:**
```typescript
import { Request, Response, NextFunction } from 'express'
import jwt from 'jsonwebtoken'

declare global {
  namespace Express {
    interface Request {
      user?: {
        userId: string
        email: string
      }
    }
  }
}

export async function authenticate(req: Request, res: Response, next: NextFunction) {
  try {
    const authHeader = req.headers.authorization

    if (!authHeader?.startsWith('Bearer ')) {
      return res.status(401).json({ error: 'No token provided' })
    }

    const token = authHeader.split(' ')[1]

    const decoded = jwt.verify(token, process.env.JWT_SECRET!) as any

    req.user = {
      userId: decoded.userId,
      email: decoded.email
    }

    next()
  } catch (error) {
    if (error instanceof jwt.TokenExpiredError) {
      return res.status(401).json({ error: 'Token expired' })
    }
    return res.status(401).json({ error: 'Invalid token' })
  }
}

export function authorize(...roles: string[]) {
  return async (req: Request, res: Response, next: NextFunction) => {
    if (!req.user) {
      return res.status(401).json({ error: 'Not authenticated' })
    }

    const user = await User.findById(req.user.userId)

    if (!user || !roles.includes(user.role)) {
      return res.status(403).json({ error: 'Insufficient permissions' })
    }

    next()
  }
}
```

### **Rate Limiting**

```typescript
import rateLimit from 'express-rate-limit'

export const authLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 5, // 5 requests per window
  message: 'Too many login attempts, please try again later',
  standardHeaders: true,
  legacyHeaders: false
})

// Usage
app.post('/api/auth/login', authLimiter, authController.login)
```

---

## Environment Variables

```bash
# JWT
JWT_SECRET=your-super-secret-key-min-32-chars
JWT_REFRESH_SECRET=your-refresh-secret-key
JWT_EXPIRES_IN=15m
JWT_REFRESH_EXPIRES_IN=7d

# OAuth - Google
GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=your-client-secret
GOOGLE_REDIRECT_URI=http://localhost:3000/api/auth/google/callback

# OAuth - GitHub
GITHUB_CLIENT_ID=your-github-client-id
GITHUB_CLIENT_SECRET=your-github-client-secret
GITHUB_REDIRECT_URI=http://localhost:3000/api/auth/github/callback

# Email
SMTP_HOST=smtp.sendgrid.net
SMTP_PORT=587
SMTP_USER=apikey
SMTP_PASSWORD=your-sendgrid-api-key
FROM_EMAIL=[email protected]
```

---

## API Routes

```typescript
// routes/auth.routes.ts
import { Router } from 'express'
import { AuthController } from '../controllers/auth.controller'
import { authenticate } from '../middleware/auth.middleware'
import { authLimiter } from '../middleware/rate-limit'

const router = Router()
const authController = new AuthController()

// Registration & Login
router.post('/register', authController.register)
router.post('/login', authLimiter, authController.login)
router.post('/refresh', authController.refreshToken)
router.post('/logout', authenticate, authController.logout)

// Email Verification
router.post('/verify-email', authController.verifyEmail)
router.post('/resend-verification', authController.resendVerification)

// Password Reset
router.post('/forgot-password', authLimiter, authController.forgotPassword)
router.post('/reset-password', authController.resetPassword)

// OAuth
router.get('/google', authController.googleLogin)
router.get('/google/callback', authController.googleCallback)
router.get('/github', authController.githubLogin)
router.get('/github/callback', authController.githubCallback)

// Profile
router.get('/me', authenticate, authController.getProfile)
router.patch('/me', authenticate, authController.updateProfile)
router.post('/change-password', authenticate, authController.changePassword)

export default router
```

---

## Related Commands

- `/env-config-setup` - Generate environment config
- `/express-api-scaffold` - Generate Express API
- `/fastapi-scaffold` - Generate FastAPI

---

**Secure authentication. Easy integration. Production-ready.** 

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.