0

Problem: I have to integrate with an existing repo that has been built via Next.js and I need to sign in to the app via an endpoint/url. I'm trying to leverage the signIn method of NextAuth.js but it keeps complaining about ReferenceError: window is not defined.

Testing Approach

  1. Add a CredentialsProvider to [...nextauth].tsx:
const providers: Provider[] = [
  
..., //existing providers

  CredentialsProvider({
    id: "jwt_auth",
    name: "JWT-Auth",
    credentials: {
      email: { label: "Username", type: "text"},
      password: { label: "Password", type: "password" },
    },
    async authorize(credentials, req) {
      return {
        id: "usr123",
        username: "testUser",
      };
    },
  }),
];
  1. Under /web/pages/api/auth/jwt.js
import { NextApiRequest, NextApiResponse } from "next";
import { signIn } from "next-auth/react";

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  await signIn<"credentials">("jwt_auth", {
    email: "test@example.com",
    password: "myPassWord",
    redirect: false,
  });

  res.status(201).json({ message: "Logged in user" });
}

This is simply setting up dummy endpoints/functions that simply go through the "success scenario" to see how this plays out. However, a GET/POST at /api/auth/jwt keeps failing with ReferenceError: window is not defined. I presume the signIn method is somehow dependent on the presence of a UI.

Question(s): How should I go about implementing an API-based sign-in? Or must I hack together an endpoint that actually returns an HTML, just so as to make this sign-in work?

Yilmaz
  • 35,338
  • 10
  • 157
  • 202
PhD
  • 11,202
  • 14
  • 64
  • 112

1 Answers1

0

we use signIn inside jsx to initiate the signIn process. this library works like redux-saga library, it starts the process on the client side and behind the scene next-auth library handles the rest

import { signIn } from "next-auth/react";

// inside submitHandler or onClick handler run this code
await signIn("credentials", {
      // if signin fails, i dont want to redirect automatically, i want to handle it on client side
      redirect: false,
      email,
      password,
    });

this will initiate the authorize function that you have in your code. this function's job is to reach the database and verifies the credentials. if the verification is success, you should return the user. after this function, next-auth has two callbacks

CredentialsProvider({
  // this will create input for you to enter at http://localhost:3000/api/auth/signin
  credentials: {
    username: {
      label: "Email",
      type: "email",
      placeholder: "palaceholder",
    },
    password: { label: "Password", type: "password" },
  },
  async authorize(credentials) {
       // here reach the db and implement verification
 }}),
],
// Callbacks are asynchronous functions you can use to control what happens when an action is performed.
callbacks: {
  //   jwt callback is only called when token is created
  jwt: async ({ token, user }) => {
    user && (token.user = user);
    // you return those so that you can access them in the app via hooks
    return Promise.resolve(token);
  },
  session: async ({ session, token }) => {
    // session callback is called whenever a session for that particular user is checked
    // we can add more properties here to the session obj
    session.user = token.user;
    return Promise.resolve(session);
  },
},

if you visit this api route "http://localhost:3000/api/auth/signin" you can enter credentials

enter image description here

for complete next-auth4 set up

Yilmaz
  • 35,338
  • 10
  • 157
  • 202
  • I'm not sure I follow. How does what you've shown actually allow an API login to happen? Such callbacks are already existing and simply `return true` from `credentials` based auth. – PhD Feb 21 '23 at 23:53
  • @PhD once you correctly implemented the setup,endpoints will be created by next-aut. there is no `/api/auth/jwt`. endpoints here: https://next-auth.js.org/getting-started/rest-api – Yilmaz Feb 22 '23 at 00:00
  • if you want to implement your own, use `import { getToken } from "next-auth/jwt"; ` this to get the token and respond – Yilmaz Feb 22 '23 at 00:01
  • I'm still confused. There is no "UI" being presented. We simply send all information to an api endpoint that calls `signIn`. But this doesn't seem to work. I'm unable to find this `signIn` function under the hood so that I can do the auth calls manually...is there a way to perform a sign in but without the call to `signIn` that depends on `window`? – PhD Feb 22 '23 at 00:55