{"library":"remix-auth-steam","title":"Remix Auth Steam Strategy","description":"remix-auth-steam provides a specialized authentication strategy for integrating Steam OpenID into Remix applications via the `remix-auth` library. Currently at version 1.0.4, this package acts as a bridge, enabling developers to leverage Steam's authentication flow within their Remix projects on Node.js runtimes. While it doesn't specify a strict release cadence, updates appear to be made on demand to address bug fixes, as seen in recent patch versions. Its primary differentiator is its focused implementation for Steam, building upon the extensible architecture of `remix-auth`. Developers should be aware of its specific dependency on `@remix-run/server-runtime` and `remix-auth` itself, and ensure their Remix environment is configured for server-side operations, as browser or edge worker support for Steam OpenID directly is not fully tested or guaranteed by this package. It ships with TypeScript types for improved developer experience.","language":"javascript","status":"active","last_verified":"Wed Apr 22","install":{"commands":["npm install remix-auth-steam"],"cli":null},"imports":["import { SteamStrategy } from 'remix-auth-steam';","import type { SteamStrategyVerifyParams } from 'remix-auth-steam';","import { authenticator } from '~/services/auth.server';"],"auth":{"required":false,"env_vars":[]},"quickstart":{"code":"import { createCookieSessionStorage, redirect } from \"@remix-run/node\";\nimport type { LoaderFunction, ActionFunction } from \"@remix-run/node\";\nimport { Authenticator } from \"remix-auth\";\nimport { SteamStrategy, SteamStrategyVerifyParams } from \"remix-auth-steam\";\nimport { useLoaderData, Form, Link } from \"@remix-run/react\";\nimport React from \"react\";\n\n// app/services/session.server.ts\n// Helper to calculate cookie expiration\nconst calculateExpirationDate = (days: number) => {\n  const expDate = new Date();\n  expDate.setDate(expDate.getDate() + days);\n  return expDate;\n};\n\n// Session storage setup\nexport let sessionStorage = createCookieSessionStorage({\n  cookie: {\n    name: \"_session\",\n    sameSite: \"lax\",\n    path: \"/\",\n    httpOnly: true,\n    secrets: [process.env.SESSION_SECRET ?? \"super-secret-dev-key\"], // IMPORTANT: Use a strong, production secret from environment variables\n    secure: process.env.NODE_ENV === \"production\",\n    expires: calculateExpirationDate(7),\n  },\n});\n\nexport let { getSession, commitSession, destroySession } = sessionStorage;\n\n// app/services/auth.server.ts\n// Define the User type based on SteamStrategyVerifyParams\nexport type User = SteamStrategyVerifyParams;\n\n// Create an Authenticator instance\nexport let authenticator = new Authenticator<User>(sessionStorage);\n\n// Register the SteamStrategy\nauthenticator.use(\n  new SteamStrategy(\n    {\n      returnURL: \"http://localhost:3000/auth/steam/callback\",\n      apiKey: process.env.STEAM_API_KEY ?? \"YOUR_STEAM_API_KEY\", // IMPORTANT: Get your API key from https://steamcommunity.com/dev/apikey\n    },\n    // The verify callback: here you can perform additional checks or database operations\n    async (user) => {\n      // For this example, we simply return the user data provided by Steam\n      console.log(\"Steam User Authenticated:\", user.nickname, user.steamid);\n      return user;\n    }\n  ),\n  \"steam\" // The name of the strategy to be used in authenticate calls\n);\n\n// app/routes/auth/steam.tsx\n// This route initiates the Steam authentication flow\nexport let loader: LoaderFunction = async ({ request }) => {\n  return authenticator.authenticate(\"steam\", request);\n};\n\n// app/routes/auth/steam/callback.tsx\n// This route handles the callback from Steam after authentication\nexport let loader: LoaderFunction = ({ request }) => {\n  return authenticator.authenticate(\"steam\", request, {\n    successRedirect: \"/\", // Redirect to home on success\n    failureRedirect: \"/login\", // Redirect to login on failure\n  });\n};\n\n// app/routes/login.tsx\nexport default function Login() {\n  return (\n    <div style={{ fontFamily: \"system-ui, sans-serif\", lineHeight: \"1.4\" }}>\n      <h1>Login</h1>\n      <p>You need to log in to access this page.</p>\n      <Link to=\"/auth/steam\">\n        <button>Login with Steam</button>\n      </Link>\n    </div>\n  );\n}\n\n// app/routes/index.tsx\nexport let loader: LoaderFunction = async ({ request }) => {\n  // Check if the user is authenticated\n  const user = await authenticator.isAuthenticated(request);\n  return user;\n};\n\nexport default function Index() {\n  const user = useLoaderData<User | null>();\n\n  return (\n    <div style={{ fontFamily: \"system-ui, sans-serif\", lineHeight: \"1.4\" }}>\n      {user ? (\n        <>\n          <h1>Welcome, {user.nickname}!</h1>\n          <p>Your SteamID: {user.steamid}</p>\n          <Form action=\"/logout\" method=\"post\">\n            <button type=\"submit\">Logout</button>\n          </Form>\n        </>\n      ) : (\n        <>\n          <h1>Not Authenticated</h1>\n          <p>\n            <Link to=\"/login\">Login with Steam</Link>\n          </p>\n        </>\n      )}\n    </div>\n  );\n}\n\n// app/routes/logout.tsx\nexport let action: ActionFunction = async ({ request }) => {\n  // Destroy the session and redirect to the login page\n  await authenticator.logout(request, { redirectTo: \"/login\" });\n  return redirect(\"/login\");\n};","lang":"typescript","description":"This quickstart demonstrates a complete Steam authentication flow in a Remix application, including session management, strategy configuration, and protected routes. It shows how to initialize the `SteamStrategy`, handle Steam callbacks, and display user authentication status.","tag":null,"tag_description":null,"last_tested":null,"results":[]},"compatibility":null}