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

jaeyong Kim님의 프로필 이미지

작성한 질문수

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

next-auth로 로그인하기

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

24.02.06 15:30 작성

·

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
질문자

2024. 02. 06. 16:29

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

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

2024. 02. 06. 16:50

아닛 이런 버그가...

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

2024. 02. 06. 17:03

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

1

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

2024. 02. 06. 15:38

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

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

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

2024. 02. 06. 15:42

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

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

2024. 02. 06. 15:44

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

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

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

2024. 02. 06. 15:47

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

 

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

2024. 02. 06. 15:51

그러면 auth.ts에서

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

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

2024. 02. 06. 15:57

auth.ts에서

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

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

2024. 02. 06. 16:01

그래서 그런 것 같은데요.

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

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

2024. 02. 06. 16:03

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

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

2024. 02. 06. 16:06

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

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

2024. 02. 06. 16:12

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

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

2024. 02. 06. 16:19

혹시 몰라서 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

choiDev님의 프로필 이미지

2024. 02. 08. 16:33

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