해결된 질문
작성
·
528
0
관련된 질문이 있나 찾아보고 혼자 코드 비교해보며 고군분투했지만 이유를 알 수가 없어 질문을 남깁니다!
질문
(afterLogin) > _component > LogoutButton.tsx 파일에서 useSession() 훅을 통하여 받아오는 data가 없어
if(!me?.user) 문에서 return 처리가 되어 로그아웃 버튼이 렌더링 되지 않습니다 -> 로그인이 제대로 되지 않는 것 같습니다
관련되서 추적을 해보니 터미널 창에 아래와 같은 에러가 뜹니다
네트워크 탭에서 session의 경우 response가 null로 넘어옵니다
application의 cookie또한 담기지 않습니다
아래는 관련된 파일들의 코드입니다..
mocks > handlers.ts
auth.ts
middleware.ts
[...nextauth] > route.ts
package.json
혹시나 다른분들도 저 같은 경우가 있으신 분들은 답변 한번 부탁드리겠습니다
답변 3
2
아뇨 여기 말고 signin 함수 호출할 때의 네트워크탭을 봐야합니다. 거기가 프론트 next-auth.session-token 쿠키 넣는 곳입니다. 그게 없어서 로그인 유지가 안 되는 겁니다.
/api/login 안에 console.log 찍을시에 정상출력되구요
authorize 함수에서 process url 경로 정상적으로 나옵니다
방금 이것저것 수정하다가 해결한 것 같아요
근데 해결하게 된 원인이 user 데이터에 nickname을 한글로 할 경우 next-auth.session-token 쿠키가 안쌓입니다..
하지만 영어로 할 경우는 쌓이네요 ..
0
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
혹시 User[0] 데이터랑 signIn 호출하는 곳 import 는 뭐로 되어있나요?
session null 로 되는거 얼마전에 많이 경험했었는데 ,, 기억이 잘 안나네요
AUTH_URL이랑 auth.ts 부분도 전체 코드 올려주시면 좋을 것 같아요
답변 감사합니다 대원님
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 호출하는 곳도 보여주세요! 글 내용에 없습니당
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의 데이터가 안담겨있습니다,, ㅎㅎ
대원님 답변 감사했습니다
해결했어요
User 데이터에 한글을 넣어 handler.ts에 있는 HttpResponse 에 들어가면 원인은 모르지만 로그인이 정상적으로 쿠키가 생성이 되지 않더라구요...
위에 제로초님에게도 답변은 따로 드렸으나 찾아봐도 정확한 원인은 모르겠네요,, 감사했습니다
네 위에 이미지 올려드린 것 처럼
응답헤더에 Set-Cookie 넣어놓고 있습니다!