Nekonyx / next-auth-steam

Steam authentication provider for next-auth
70 stars 18 forks source link

Getting session in API route #11

Closed maxeth closed 1 year ago

maxeth commented 1 year ago

Hey,

first of all, thanks for this easy Steam OAuth integration.

The next-auth docs mention the following snippet with getServerSession for getting a user's session within API routes (I came across it as my attempt to get the session with getSession({req}) returns null within my API routes):

import { authOptions } from 'pages/api/auth/[...nextauth]'
import { getServerSession } from "next-auth/next"

export default async function handler(req, res) {
  const session = await getServerSession(req, res, authOptions) // <---- authOptions is supposed to be an object

  if (!session) {
    res.status(401).json({ message: "You must be logged in." });
    return;
  }

  return res.json({
    message: 'Success',
  })
}

Here, authOptions - e.g the object with {providers: [...], secret: [...]} - has to be passed as a "pure" object.

Your README, however, shows a setup like this in [...nextauth].ts:

export default function handler(req: NextApiRequest, res: NextApiResponse) {
  return NextAuth(req, res, {
  [...]
  providers: [
      SteamProvider(req, {
   [...]
    }
  ]
 }
}

So the SteamProvider expects a req. This makes their way of passing the authOptions as a pure object impossible when using your package as one of the providers, or am I missing something?

Now I'm wondering: is there a common way to use getServerSession with your Steam OAuth integration? Or am I the only one getting null when calling getSession({req}) inside API routes? πŸ˜„

maxeth commented 1 year ago

I came up with this solution (?):

export default function handler(req: NextApiRequest, res: NextApiResponse) {
  return NextAuth(req, res, authOptions(req));
}

export function authOptions(req: NextApiRequest): AuthOptions {
  return {
    providers: [
      SteamProvider(req, {
       [...]
}]
}
}

and then pass the req object to authOptions to get a config object that getServerSession accepts:

 const session = await getServerSession(req, res, authOptions(req));

This hasn't caused any unexpected behaviour so far, and after taking a look at what this package does with req internally, I don't see any issue with this solution at first glance.

I'm still interested in how you guys deal with getServerSession and this package πŸ˜„

Nekonyx commented 1 year ago

Hey @maxeth, thanks for your interest in my project.

There's an example of using getServerSession: https://github.com/Nekonyx/next-auth-steam/tree/master/examples/get-server-session

In short, yes, we get auth options in method:

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  return NextAuth(req, res, getAuthOptions(req))
}

export function getAuthOptions(req: NextApiRequest): AuthOptions {
  return {
    providers: [
      SteamProvider(req, {
        clientSecret: process.env.STEAM_SECRET!,
        callbackUrl: 'http://localhost:3000/api/auth/callback'
      })
    ],
    callbacks: {
      jwt({ token, account, profile }) {
        if (account?.provider === PROVIDER_ID) {
          token.steam = profile
        }

        return token
      },
      session({ session, token }) {
        if ('steam' in token) {
          // @ts-expect-error
          session.user.steam = token.steam
        }

        return session
      }
    }
  }
}