인프런 커뮤니티 질문&답변

jaeyong Kim님의 프로필 이미지
jaeyong Kim

작성한 질문수

Next + React Query로 SNS 서비스 만들기

next-auth로 로그인하기

안녕하세요 Next-auth 질문을 올려봅니다.

작성

·

1.1K

·

수정됨

3

next-auth로 로그인하기의 강의를 듣던 도중 오류가 생겨 게시판에 글을 남겨봅니다.
문제는 Login 모달에서 로그인을 하였을 때 http://localhost:3000/api/auth/error 로 페이지가 이동 되어집니다.

next-auth

  "next-auth": "^5.0.0-beta.3",



.env .env.localAUTH_URL=http://localhost:9090 를 넣어 두었고

route.ts

export { GET, POST } from "@/auth";

handlers.ts

import { http, HttpResponse, StrictResponse } from "msw";
import { faker } from "@faker-js/faker";

const User = [
  { id: "zeroCho", nickName: "zero", image: "/yRsRRjGO.jpg" },
];

export const handlers = [
  // 로그인
  http.post("/api/login", () => {
    console.log("로그인");
    return HttpResponse.json(User[1], {
      headers: {
        "Set-Cookie": "connect.sid=msw-cookie;HttpOnly;Path=/", // Http cookie 넣어주기
      },
    });
  }),
  // 로그아웃
  http.post("/api/logout", () => {
    console.log("로그아웃");
    return new HttpResponse(null, {
      headers: {
        "Set-Cookie": "connect.sid=;HttpOnly;Path=/;Max-Age=0",
      },
    });
  }),
  // 회원 가입
  http.post("/api/users", async ({ request }) => {
    console.log("회원가입");
    // return HttpResponse.text(JSON.stringify('user_exists'), {
    //   status: 403,
    // })

    return HttpResponse.text(JSON.stringify("ok"), {
      headers: {
        "Set-Cookie": "connect.sid=msw-cookie;HttpOnly;Path=/;Max-Age=0",
      },
    });
  }),
];

auth.ts

import NextAuth from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";
export const {
  handlers: { GET, POST },
  auth,
  signIn,
} = NextAuth({
  pages: {
    signIn: "/i/flow/login",
    newUser: "/i/flow/signup",
  },
  providers: [
    CredentialsProvider({
      async authorize(credentials) {
        const authResponse = await fetch(`${process.env.AUTH_URL}/api/login`, {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
          },
          body: JSON.stringify({
            id: credentials.username,
            password: credentials.password,
          }),
        });

        if (!authResponse.ok) {
          return null;
        }

        const user = await authResponse.json();
        return {
          email: user.id,
          name: user.nickname,
          image: user.image,
          ...user,
        };
      },
    }),
  ],
});

LoginModal.tsx

"use client";
import React, { ChangeEventHandler, FormEventHandler, useState } from "react";
import styles from "./loginModal.module.css";
import { redirect, useRouter } from "next/navigation";
// client
import { signIn } from "next-auth/react";

export function LoginModal() {
  const [id, setId] = useState<string>("");
  const [password, setPassword] = useState<string>("");
  const [message, setMessage] = useState<string>("");
  const router = useRouter();

  const onSubmit: FormEventHandler<HTMLFormElement> = async (e) => {
    e.preventDefault();
    setMessage("");
    try {
      await signIn("credentials", {
        username: id,
        password,
        redirect: false,
      });
      router.replace("/home");
    } catch (err) {
      console.error(err);
      setMessage("아이디와 비밀번호가 일치하지 않습니다.");
    }
  };
  const onClickClose = () => {
    router.back();
  };

  const onChangeId: ChangeEventHandler<HTMLInputElement> = (e) => {
    setId(e.target.value);
  };

  const onChangePassword: ChangeEventHandler<HTMLInputElement> = (e) => {
    setPassword(e.target.value);
  };

  return (
    <div className={styles.modalBackground}>
      <div className={styles.modal}>
        <div className={styles.modalHeader}>
          <button className={styles.closeButton} onClick={onClickClose}>
            <svg
              width={24}
              viewBox="0 0 24 24"
              aria-hidden="true"
              className="r-18jsvk2 r-4qtqp9 r-yyyyoo r-z80fyv r-dnmrzs r-bnwqim r-1plcrui r-lrvibr r-19wmn03"
            >
              <g>
                <path d="M10.59 12L4.54 5.96l1.42-1.42L12 10.59l6.04-6.05 1.42 1.42L13.41 12l6.05 6.04-1.42 1.42L12 13.41l-6.04 6.05-1.42-1.42L10.59 12z"></path>
              </g>
            </svg>
          </button>
          <div>로그인하세요.</div>
        </div>
        <form onSubmit={onSubmit}>
          <div className={styles.modalBody}>
            <div className={styles.inputDiv}>
              <label className={styles.inputLabel} htmlFor="id">
                아이디
              </label>
              <input
                id="id"
                className={styles.input}
                value={id}
                onChange={onChangeId}
                type="text"
                placeholder=""
              />
            </div>
            <div className={styles.inputDiv}>
              <label className={styles.inputLabel} htmlFor="password">
                비밀번호
              </label>
              <input
                id="password"
                className={styles.input}
                value={password}
                onChange={onChangePassword}
                type="password"
                placeholder=""
              />
            </div>
          </div>
          <div className={styles.message}>{message}</div>
          <div className={styles.modalFooter}>
            <button className={styles.actionButton} disabled={!id && !password}>
              로그인하기
            </button>
          </div>
        </form>
      </div>
    </div>
  );
}

 

혹시 같은 문제를 겪으신 분이 있었을까요? 아니면 겪으신 분 중에 해결 하신 분이 있으면 도움 부탁드립니다.

답변 3

2

jaeyong Kim님의 프로필 이미지
jaeyong Kim
질문자

해결 되었습니다
@auth/core 버젼을 다운그레이드 시켰더니 작동이 됩니다.
관심 갖고 함께 찾아주셔서 감사합니다.

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

아닛 이런 버그가...

jaeyong Kim님의 프로필 이미지
jaeyong Kim
질문자

강사님 코드와 다른 점을 여러군데 찾아보다가 버젼이 조금 다른듯 하여 다운그레이드 시켰습니다.

1

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

auth.ts에서 console.log(authResponse); 해서 로깅해보시고, msw쪽에서도 콘솔에 로그인 출력되나요?

일단 하나 발견한 건 nickName 대신 nickname 쓰셔야 합니다.

jaeyong Kim님의 프로필 이미지
jaeyong Kim
질문자

강사님이 말씀해주신 log를 출력 해보았을 때에는 로그는 출력이 안됩니다.

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

npm run mock이 실행된 상태인가요?

Mock server is running on port: 9090은 출력되나요?

jaeyong Kim님의 프로필 이미지
jaeyong Kim
질문자

image
네 위의 이미지와 같이 실행중입니다.

 

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

그러면 auth.ts에서

console.log(process.env.AUTH_URL) 해보시겠어요?

jaeyong Kim님의 프로필 이미지
jaeyong Kim
질문자

auth.ts에서

console.log(process.env.AUTH_URL) 로그에 출력 안됩니다.

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

그래서 그런 것 같은데요.

.env 파일의 경로가 package.json과 동일한 폴더에 있는 것 맞나요?

jaeyong Kim님의 프로필 이미지
jaeyong Kim
질문자

image
네 같은 위치에 적용해 두었습니다.

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

음.. 다른 env들은 나오나요? NEXT_PUBLIC_BASE_URL같은 것들요.

jaeyong Kim님의 프로필 이미지
jaeyong Kim
질문자

auth.ts 에서는 log는 출력이 안됩니다.

jaeyong Kim님의 프로필 이미지
jaeyong Kim
질문자

혹시 몰라서 node_modules 와 .next 도 모두 삭제해보고 npm install 한 뒤 실행 해보아도 동일한 결과가 나옵니다. 버튼을 눌렀을 때 페이지 가 이동 되며 "Error: This action with HTTP GET is not supported." 이 에러가 표시되며

터미널에는 아래 와 같은 에러가 나옵니다.
UnknownAction: Cannot parse action at /api/auth/error .Read more at https://errors.authjs.dev#unknownaction

0

저도 같은 문제를 겪었고, 강사님과 next-auth 랑 @auth/core 버전을 일치 시키니 해결되네요

jaeyong Kim님의 프로필 이미지
jaeyong Kim

작성한 질문수

질문하기