{
  "id": 10869858,
  "title": "Building a Choose-Your-Own-Adventure API with NestJS — Part 4: Auth",
  "url": "https://urgent.news/2026/09/30/building-a-choose-your-own-adventure-api-with-nestjs-part-4-auth",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-09-30T05:43:09.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/_notbu7ch/building-a-choose-your-own-adventure-api-with-nestjs-part-4-auth-58nm"
  },
  "original_language": "en",
  "account": "Part 4 of the Grimoire API series brings real accounts and authentication to the project. The previous stages focused on validated endpoints, persistence, and the XP/badge rules. This post finally replaces the placeholder DEFAULT_PLAYER_ID with genuine user accounts. Every progress endpoint will now be scoped to the authenticated user.\n\nNestJS simplifies authentication by wrapping Passport, a widely-used Node authentication library, behind its own decorators. Two Passport strategies are employed to meet the project's requirements: the Local strategy for email and password login, and the JWT strategy for validating bearer tokens on subsequent requests.\n\nA Guard is responsible for blocking requests before reaching a controller method if authentication fails. The JwtAuthGuard class is a simple wrapper that uses the jwt strategy from @nestjs/passport to handle authentication.\n\nPassword hashing is crucial for security. The bcrypt library is used to hash passwords during sign-up and compare them during login. The cost factor (10 in bcrypt.hash(password, 10)) determines the number of hashing rounds, balancing speed and security. In this case, 10 is a reasonable default for a learning project, but production environments may require further tuning.\n\nThe JWT strategy, implemented in JwtStrategy, uses PassportStrategy to handle token validation. It extracts the token from the authentication header using fromAuthHeaderAsBearerToken, and the JWT_SECRET is fetched from environment variables. The validate method then checks the payload and returns the user object, which is signed and returned as an access token using the jwtService.",
  "summary": "Part 4 of the Grimoire API series. So far: a validated endpoint ( Part 1 ), persistence ( Part 2 ), and the actual XP/badge rules ( Part 3 ) — all running against one hardcoded \"default player.\" This post finally gets rid of that placeholder. Retiring DEFAULT_PLAYER_ID Since Part 2, every POST /progress/choice call has quietly advanced the same fake user. It was a deliberate shortcut to build…",
  "key_points": [
    "Replace placeholder DEFAULTPLAYERID with genuine user accounts",
    "Use NestJS and Passport for authentication with Local and JWT strategies",
    "Hash passwords with bcrypt and validate JWT tokens in JwtStrategy"
  ],
  "editors_take": "This development brings the Grimoire API closer to a production-ready state by introducing genuine user accounts and authentication, replacing placeholder IDs and enhancing security with password hashing and token validation.",
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}