HilliamT / nextjs-steam-auth

An example NextJS application that configures Passport-based Steam authentication via Next Connect

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

NextJS Steam Authentication

πŸ“– Table of Contents

πŸ‘‹ Introduction

NextJS is a React-based web framework that aims to deliver websites as statically as possible. This can provide many performance and development benefits over a framework like Express.

Setting up authentication can be tricky, especially with OpenID login systems such as Steam (there are not many implementations avaiable, let alone in NextJS). This repository is an example of how one may go about injecting Steam user authentication. This allows you to use Steam authentication with a NextJS API backend, and implement such components into your own project

πŸ”Œ Getting Started

After downloading the project, you should install all of the required dependencies.

$ npm install

Fill in a .env file with the following keys filled, much like .env.sample (Remove .sample off the file name)

DOMAIN=http://localhost:3000 # Where this app will run
SESSION_SECRET=ABCD # 32+ char random string
STEAM_API_KEY= # Your Steam API Key

You can run the web application in development mode.

$ npm run dev

You can also test the web application for production if you feel the need.

$ npm run build
$ npm start

βš™οΈ How It Works

  • You make a request to the api/steam/login endpoint
  • Redirects you to steam oauth with a clientID (somehow) via the passport middleware in passport.ts
  • After you authenticate your account, it redirects you to the frontend with a cookie being sent to the backend.
  • The router directs the data received from the authentication, and sends it to the frontend via getServerSideProps. You can access it via the user parameter in the Index function index.tsx.

πŸ’‘ Improvements To Make

This is only one example of authenticating a user with their Steam account via NextJS. There are some fixes that can be added to better development and cleanliness without making significant changes.

Isolating Middleware

path is set within login.ts, logout.ts and return.ts or the middleware will apply to all routes. An alternative solution will need to ensure that middleware set on an API route only runs on that API route. Removing path from each route handler will cause constantly redirect you back to Steam's login page.

Avoiding Manual Request Population

router works in parallel with NextJS's native router. However, it needs to be explicitly activated per React page, as seen in Index.getServerSideProps where it will populate the Request object with any additional fields picked up. This can be repetitive in nature so having router run natively or just once for all pages would be ideal. getServerSideProps receives the request of the steam profile data on the frontend.

"How to make the Steam auth a component?"

You can copy and paste the component structure on index.tsxto another component of your choice (say, steam.tsx), just ensure you have the props paramater in both the component and the page file (index.tsx) to allow getServerSideProps to inject the request object cookie from the backend. (You only need getServerSideProps on the index.tsx, or page of the rendered content).

Example

Here is our Here is Steam.tsx, our component-ized Steam authentication.

import Link from "next/link";
import router from "@/lib/auth/router";
import type { SteamProfile } from '@/lib/state/state'


export default function Steam({ user }: {user: SteamProfile}) {
    console.log(user)
	return <div style={{ textAlign: "center" }}>
		{user 
			? <div className='font-bold'>
				Welcome back!<br />
				From logging in, your SteamID is {user.id}.<br />
				You can call other APIs to get more information within `getServerSideProps` or within `lib/passport.ts`.<br />
				<Link href="/api/auth/logout">Logout</Link>
			</div>

			: <div>
				Welcome!<br />
				<Link href="/api/auth/login">Login</Link>
			</div>
		}
	</div>;
}

Now here is our index.tsx, passing the request object to the Steam function.

import router from '@/lib/auth/router'
import type { SteamProfile } from '@/lib/passport'
import type { NextSteamAuthApiRequest } from "../lib/router";


import Steam from '@/lib/components/auth/Steam';

export default function Home({ user }: {user: SteamProfile}) {
  return (
    <>
    <Steam user={user}/>
    
    </>
  )
}

export async function getServerSideProps({ req, res}:{req: NextSteamAuthApiRequest, res: NextApiResponse}) {
  await router.run(req, res);
  return { props: { user: req.user || null } };
}

πŸ“š Helpful Resources

About

An example NextJS application that configures Passport-based Steam authentication via Next Connect

License:MIT License


Languages

Language:TypeScript 97.0%Language:JavaScript 3.0%