강의

멘토링

커뮤니티

Cộng đồng Hỏi & Đáp của Inflearn

Hình ảnh hồ sơ của mjuikl75884824
mjuikl75884824

câu hỏi đã được viết

Tiếp theo + Tạo dịch vụ SNS bằng React Query

Màn hình khác nhau dựa vào trạng thái đăng nhập

로그인을 할 시에 useSession에서 me data를 받아오지를 못하는 것 같습니다

Đã giải quyết

Viết

·

656

0

관련된 질문이 있나 찾아보고 혼자 코드 비교해보며 고군분투했지만 이유를 알 수가 없어 질문을 남깁니다!

 

질문

(afterLogin) > _component > LogoutButton.tsx 파일에서 useSession() 훅을 통하여 받아오는 data가 없어
if(!me?.user) 문에서 return 처리가 되어 로그아웃 버튼이 렌더링 되지 않습니다 -> 로그인이 제대로 되지 않는 것 같습니다

 

관련되서 추적을 해보니 터미널 창에 아래와 같은 에러가 뜹니다

스크린샷 2024-02-15 오후 11.20.46.png

네트워크 탭에서 session의 경우 response가 null로 넘어옵니다

스크린샷 2024-02-15 오후 11.20.20.png

application의 cookie또한 담기지 않습니다

스크린샷 2024-02-15 오후 11.21.28.png

 

아래는 관련된 파일들의 코드입니다..

 

mocks > handlers.ts

스크린샷 2024-02-15 오후 11.24.37.png

auth.ts

스크린샷 2024-02-15 오후 11.24.26.png

middleware.ts

스크린샷 2024-02-15 오후 11.24.48.png

[...nextauth] > route.ts

스크린샷 2024-02-15 오후 11.24.56.png

package.json

스크린샷 2024-02-15 오후 11.26.21.png

 

혹시나 다른분들도 저 같은 경우가 있으신 분들은 답변 한번 부탁드리겠습니다

 

reactnext.jsreact-querynext-authmsw

Câu trả lời 3

2

zerocho님의 프로필 이미지
zerocho
Người chia sẻ kiến thức

이건 로그인부터 다시 보셔야 합니다. 로그인 시 응답 헤더에 Set-Cookie 있나요?

mjuikl75884824님의 프로필 이미지
mjuikl75884824
Người đặt câu hỏi

네 위에 이미지 올려드린 것 처럼

응답헤더에 Set-Cookie 넣어놓고 있습니다!

 

스크린샷 2024-02-15 오후 11.56.04.png

zerocho님의 프로필 이미지
zerocho
Người chia sẻ kiến thức

아뇨 여기 말고 signin 함수 호출할 때의 네트워크탭을 봐야합니다. 거기가 프론트 next-auth.session-token 쿠키 넣는 곳입니다. 그게 없어서 로그인 유지가 안 되는 겁니다.

zerocho님의 프로필 이미지
zerocho
Người chia sẻ kiến thức

http.post('/api/login' 안에서는 console.log찍어서 로그인 시 출력되는지 확인해보시고, authorize 함수에서는 process.env.AUTH_URL 콘솔로그 찍어보세요.

mjuikl75884824님의 프로필 이미지
mjuikl75884824
Người đặt câu hỏi

/api/login 안에 console.log 찍을시에 정상출력되구요
authorize 함수에서 process url 경로 정상적으로 나옵니다

 

방금 이것저것 수정하다가 해결한 것 같아요

근데 해결하게 된 원인이 user 데이터에 nickname을 한글로 할 경우 next-auth.session-token 쿠키가 안쌓입니다..

하지만 영어로 할 경우는 쌓이네요 ..

스크린샷 2024-02-16 오전 12.40.24.png

 

0

zerocho님의 프로필 이미지
zerocho
Người chia sẻ kiến thức

npm i @auth/core@0.27 next-auth@5.0.0-beta.11 msw@2.1
이렇게 설치하고 .env에서 AUTH_URL을 지웁니다. 그리고 auth.ts에서 NEXT_PUBLIC_BASE_URL을 대신 씁니다. .env에 AUTH_URL을 쓰지 않는 게 핵심입니다.

const authResponse = await fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/api/login`, {

아직 msw@2.2의 버그는 해결하지 못했습니다.
https://github.com/mswjs/msw/issues/1658#issuecomment-1953599080
이런 식으로 버그 제기를 하고는 있으나 언제 고쳐질 지는 모르겠습니다. 해결되는대로 다시 공유드리겠습니다.

0

npm run mock 안하신거 같은데요?

mjuikl75884824님의 프로필 이미지
mjuikl75884824
Người đặt câu hỏi

답변 감사합니다 npm run mock 되어 있는 상태입니다

스크린샷 2024-02-15 오후 11.38.22.png

혹시 User[0] 데이터랑 signIn 호출하는 곳 import 는 뭐로 되어있나요?
session null 로 되는거 얼마전에 많이 경험했었는데 ,, 기억이 잘 안나네요

AUTH_URL이랑 auth.ts 부분도 전체 코드 올려주시면 좋을 것 같아요

mjuikl75884824님의 프로필 이미지
mjuikl75884824
Người đặt câu hỏi

답변 감사합니다 대원님

auth.ts 파일 전체 코드입니다

//==============================

import NextAuth from 'next-auth';
import CredentialsProvider from 'next-auth/providers/credentials';
import KakaoProvider from 'next-auth/providers/kakao';

export const {
  handlers: { GET, POST } /** API 라우트 */,
  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 {
          id: user.id,
          name: user.nickname,
          image: user.image,
          ...user,
        };
      },
    }),
    // KakaoProvider({...})
  ],
});

//==============================

 

handlers.ts User[0] 넣는 곳 입니다

import { http, HttpResponse } from 'msw';
import ECOM from '/public/images/ecom.png';

const User = [
  {
    userId: 1,
    nickname: 'eden',
    id: 'eden',
    image: '/public/images/ecom.png',
  },
];

export const handlers = [
  http.post('/api/login', () => {
    return HttpResponse.json(User[0], {
      headers: {
        'Set-Cookie': 'connect.sid=msw-cookie;HttpOnly;Path=/',
      },
    });
  }),
  http.post('/api/logout', () => {
    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',
      },
    });
  }),
];

 

signIn 호출하는 곳은 글 내용에 코드 캡쳐있습니다

클라이언트 컴포넌트라 next-auth/react 로 import 했습니다

authReponse 콘솔찍으면 { userId: 1, nickname: 'eden', id: 'eden', image: '/public/images/ecom.png', },

잘 들어가 있나요? signIn 호출하는 곳도 보여주세요! 글 내용에 없습니당

mjuikl75884824님의 프로필 이미지
mjuikl75884824
Người đặt câu hỏi

signIn 호출하는 LoginModal.tsx 파일 코드입니다

 

'use client';

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

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('');
    try {
      await signIn('credentials', {
        username: id,
        password,
        redirect: false,
      });
      router.replace('/home');
    } catch (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>
  );
}

 

authReponse 콘솔 찍으면 데이터가 user의 데이터가 안담겨있습니다,, ㅎㅎ

mjuikl75884824님의 프로필 이미지
mjuikl75884824
Người đặt câu hỏi

대원님 답변 감사했습니다

해결했어요

User 데이터에 한글을 넣어 handler.ts에 있는 HttpResponse 에 들어가면 원인은 모르지만 로그인이 정상적으로 쿠키가 생성이 되지 않더라구요...
위에 제로초님에게도 답변은 따로 드렸으나 찾아봐도 정확한 원인은 모르겠네요,, 감사했습니다

Hình ảnh hồ sơ của mjuikl75884824
mjuikl75884824

câu hỏi đã được viết

Đặt câu hỏi