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

악보-Designer Park님의 프로필 이미지
악보-Designer Park

작성한 질문수

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

next-auth로 로그인하기

로그인시 오류페이지로 이동됩니다

해결된 질문

작성

·

362

·

수정됨

0

해당 영상에서 질문들을 참고해봐서 그나마 재영님 질문과 비슷해서 버전 문제일 수 있을 것 같아 버전도 낮춰보고 했음에도 해결이 되지 않아 새로 질문 올립니다..

 

[[[ 문제점 ]]]

아이디와 패스워드를 치고 로그인을 눌렀을 때 오류페이지로 이동됩니다.

정상적일때 경로 => [ localhost:3000/home ]

현재 이동되는 경로 => [ localhost:3000/api/auth/error ]

[ 해당 사진 ]

스크린샷 2024-03-19 오후 9.35.24.png

[ 적용했었던 버전 내역 ]

next-auth@5.0.0-beta.3

next-auth@5.0.0-beta.4

next-auth@5.0.0-beta.11

@auth/core@0.19

@auth/core@0.27

 

[ 디렉토리 구조 ]

스크린샷 2024-03-19 오후 9.30.48.png

 

[ 코드 ]

  • env

NEXT_PUBLIC_BASE_URL=http://localhost:9090
AUTH_SECRET=testtest
  • 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.NEXT_PUBLIC_BASE_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 user;
      },
    }),
  ]
});
  • mocks/handlers.ts

import {http, HttpResponse, StrictResponse} from 'msw';

export const handlers = [
    http.post('/api/login', () => {
        console.log('로그인');

        return HttpResponse.json({
            userId: 1,
            nickname: '프림입니다만',
            id: 'pream',
            image: '/5Udwvqim.jpg'
        }, {
          headers: {
            'Set-Cookie': 'connect.sid=msw-cookie;HttpOnly;Path=/'
          }
        });
    }),

    http.post('/api/logout', () => {
        console.log('로그아웃');
        
        return new HttpResponse(null, {
            headers: {
            'Set-Cookie': 'connect.sid=;HttpOnly;Path=/;Max-Age=0'
            }
        });
    }),

    http.post('/api/signup', 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'
          }
        })
    }),
];
  • @/app/(beforeLogin)/_components/LoginModal.tsx

"use client";

import { ChangeEventHandler, FormEventHandler, useState } from "react"
import style from "@/app/(beforeLogin)/_components/login.module.css";
import { signIn } from "next-auth/react";
import { useRouter } from "next/navigation";

export default function LoginModal() {

    const [id, setId] = useState('');
    const [password, setPassword] = useState('');
    const [message, setMessage] = useState('');

    const router = useRouter();
    
    const onSubmit: FormEventHandler<HTMLFormElement> = async (e) => {
        e.preventDefault();
        setMessage('');

        window.alert('aaa');

        try {
          await signIn("credentials", {
            username: id,
            password,
            redirect: false,
          });

          window.alert('bbb');

          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={style.modalBackground}>
        <div className={style.modal}>
            <div className={style.modalHeader}>
            <button className={style.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={style.modalBody}>
                <div className={style.inputDiv}>
                <label className={style.inputLabel} htmlFor="id">아이디</label>
                <input id="id" className={style.input} value={id} onChange={onChangeId} type="text" placeholder=""/>
                </div>
                <div className={style.inputDiv}>
                <label className={style.inputLabel} htmlFor="password">비밀번호</label>
                <input id="password" className={style.input} value={password} onChange={onChangePassword} type="password" placeholder=""/>
                </div>
            </div>
            <div className={style.message}>{message}</div>
            <div className={style.modalFooter}>
                <button className={style.actionButton} disabled={!id && !password}>로그인하기</button>
            </div>
            </form>
        </div>
        </div>
    )
}

여기서 onSumbit 함수 부분에서 alert를 중간에 넣었는데

window.alert('aaa')은 떴고,

확인 버튼 누르고, 다음 window.alert('bbb')가 뜨자마자 바로 에러 페이지로 이동됩니다. ( 확인 버튼 조차 못누르고 바로 이동됩니다 )

 

 

그리고 auth.ts 에서는 재영님 질문처럼 터미널 로그들이 안찍힙니다...

 

9090 서버는 잘 띄워놨었구요.

회원가입 로그는 잘 나오는데 로그인 로그는 안뜹니다.

 

 

 

답변 1

0

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

msw 콘솔에서는 '로그인'이라는 메시지가 찍히나요?

/api/auth/error로 이동할 때 프론트서버 콘솔이나 브라우저에는 메시지가 따로 없나요?

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

그리고 현재의 정확한 버전을 알려주세요. 가장 최신 버전으로 하시고 계신 건가요?

로그인 메세지는 안뜹니다.

 

브라우저에서는 아래의 사진 처럼 1개 오류가 뜹니다.

image

터미널 로그도 남기겠습니다.

○ Compiling /favicon.ico ...
 ✓ Compiled /favicon.ico in 739ms (460 modules)
 ✓ Compiled /api/auth/[...nextauth] in 76ms (462 modules)
 ⨯ No HTTP methods exported in '/Users/apple/Desktop/정리/React수업/nextjs14-z-com/src/app/api/auth/[...nextauth]/route.ts'. Export a named export for each HTTP method.
 ⨯ No HTTP methods exported in '/Users/apple/Desktop/정리/React수업/nextjs14-z-com/src/app/api/auth/[...nextauth]/route.ts'. Export a named export for each HTTP method.

 

현재 버전은 아래에 이미지 첨부하겠습니다.

image

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

${process.env.NEXT_PUBLIC_BASE_URL}}/api/login

오타네요. 보이시나요? ㅎㅎ }} 두 번 들어가 있습니다.

아 그러네요

auth.ts는 제로초님이 올려주신 깃헙에서 가져와서 해당 챕터에 맞게 수정 했었는데 오타가 있었나 봅니다.

image

 

route.ts 에서도 제가 실수했었네요.

 

export { GET, POST } from '@/auth' 여야 했는데

import { GET, POST } from '@/auth'로 작성했었네요;

 

죄송합니다

좀 더 신중히 보도록 하겠습니다.

악보-Designer Park님의 프로필 이미지
악보-Designer Park

작성한 질문수

질문하기