inflearn logo
강의

Course

Instructor

Next + Create a SNS service with React Query

Logging in with next-auth

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

1384

jaeyong Kim

3 asked

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>
  );
}

 

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

react next.js react-query next-auth msw

Answer 3

2

jaeyong Kim

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

0

zerocho

아닛 이런 버그가...

0

jaeyong Kim

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

1

zerocho

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

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

0

jaeyong Kim

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

0

zerocho

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

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

0

jaeyong Kim

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

 

0

zerocho

그러면 auth.ts에서

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

0

jaeyong Kim

auth.ts에서

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

0

zerocho

그래서 그런 것 같은데요.

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

0

jaeyong Kim

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

0

zerocho

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

0

jaeyong Kim

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

0

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

choiDev

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

캡처링부분 질문있습니다.

0

74

2

깃에 소스코드를 찾을 수 없습니다.

0

113

2

useInfiniteQuery promise와 react use 사용시 페이지 무한 로딩

0

98

1

import 파일 경로를 찾지 못 해서 에러가 발생합니다.

0

109

2

css 라이브러리 추천 부탁드립니다

0

140

2

팔로우 추천 목록이 빈 배열로 들어옵니다.

0

130

1

게시물 업로드 시 userId가 undefined로 들어가는 오류

0

119

1

useSuspenseQuery 사용 시 SSR 401 이슈 관련

0

172

1

리액트 쿼리 useinfinitequery 무한스크롤 구현 시 페이지가 이동할 경우 데이터가 보존되게 할 수 있나요??

0

184

3

폴링이 필요없는 이유

0

93

2

next Request Memoization과 react cache

0

108

2

seo 최적화 기준은 데이터 fetching인가요 아님 데이터 렌더링인가요?

0

84

2

next.js 서버fetch 에러 fallback ui 구현 방법

0

173

2

프레임워크 여론 파악법

0

125

2

필터옵션이 많은 페이지에서 서버 fetch를 하는게 맞는걸까요??

0

103

2

서버 fetch suspense 로 감싸고 새로고침 시 잠시 빈 화면이 노출된 후 fallback ui가 노출됩니다.

0

102

2

template.tsx 내 서버fetch 응답값과 클라이언트 컴포넌트 상태값 싱크가 맞지 않는 이슈

0

66

2

Auth.js 사용 시 authorize 함수가 호출되지 않습니다

0

131

2

next.js 에서 로그인에 관하여

0

138

1

Next의 route handler에 대한 질문이 있습니다.

0

101

2

게시판 리스트 만들때 use client를 어디서부터 집어넣어야할지 모르겠습니다

0

98

2

프라이빗 폴더를 해야 하는 이유가 모호한 것 같아요.

0

85

2

vanilla-extract 못찾는 문제

0

230

2

fetch 캐싱과 revalidate 관련

0

84

2