해결된 질문
24.05.27 17:15 작성
·
296
0
Next.js와 Spring boot를 사용해서 소셜 로그인을 추가하려고 합니다.
소셜 로그인의 경우 코드와 토큰을 프론트에서 관리하지 않는 것이 좋다고 하여 백엔드에서 모든 로직을 처리하고 있습니다.
현재 프론트에서 window.location.href = "http://localhost:8080/oauth2/authorization/google";
위와 같은 경로로 백엔드로 소셜 로그인 요청을 보내고
백엔드에서는 소셜 로그인을 진행한 뒤에 유저 정보를 생성하고 JWT를 생성한 뒤 응답의 헤더에 쿠키 형태로 JWT를 넣어 response.sendRedirect("http://localhost:3000/auth/social");
로 리다이렉트하고 있습니다.
프론트에서는 /auth/social
페이지에서 쿠키에 있는 JWT를 꺼내 유저 정보를 가져오는 API를 다시 호출해 유저 정보를 가져오고 있습니다.
이 후 auth.js 라이브러리를 통한 session 관리를 하고자 하는데 session을 업데이트 하려면 어떻게 해야 하나요..?
(session.user가 있는지 없는지를 통한 로그인 체크를 위해 사용한다고 이해했습니다.)
서버 컴포넌트에서 import { auth } from "@/auth";
를 통해 가져온 session에 데이터를 넣어보았지만 데이터가 제대로 들어가지 않는 것 같아 조언을 구해봅니다..
답변 1
0
2024. 05. 27. 17:21
조금 복잡하긴 한데 POST /api/auth/session을 하시면 됩니다. csrfToken을 넣으셔야 할 수 있습니다. 다음 댓글 참고하세요. 서버컴포넌트라는 가정 하에 진행됩니다.
https://github.com/nextauthjs/next-auth/discussions/9715#discussioncomment-9225447
2024. 05. 27. 23:06
지금 callbacks.jwt나 callbacks.session이 있는 상황이신가요? 지금 jwt가 아니라 session 쪽이 호출되고있는지도 모르겠습니다.
https://authjs.dev/reference/nextjs#unstable_update
이렇게 signOut같은 것 불러오는 것처럼 unstable_update를 불러서 세션 업데이트 하는 함수도 있네요.
2024. 05. 29. 11:06
최대한 시도를 해봤는데 로직을 변경해야 할 것 같습니다..ㅎㅎ
스프링과 협업할 당시 동일 window.location.href = "http://localhost:8080/oauth2/authorization/google";
API 주소로 하이퍼링크 요청을 보내면
auth.js에서 세션에 유저 정보를 등록하고자 하는데 이 때 어떤 방식으로 해야 할까요..
2024. 05. 29. 12:21
일단 oauth의 핵심은 구글이 redirect url로 요청을 쏴준다는 것이고, 그 url에서 다시 POST /api/auth/session을 호출하셔서 세션 등록을 해야합니다.
2024. 05. 29. 15:28
import { cookies } from "next/headers";
import { getUserInfo } from "./c/getUserInfo";
import { auth } from "@/auth";
import { redirect } from "next/navigation";
export default async function SocialRedirectPage() {
const cookieStore = cookies();
const accessToken = cookieStore.get("AccessToken")?.value!;
const refreshToken = cookieStore.get("RefreshToken")?.value!;
const csrfToken = cookieStore.get("authjs.csrf-token")?.value!;
const pk = cookieStore.get("Pk")?.value!;
const session = await auth();
// console.log({ accessToken, refreshToken, csrfToken });
const user = await getUserInfo(accessToken, pk);
// console.log({ user });
if (csrfToken) {
const response = await fetch(
`${process.env.NEXTAUTH_URL}/api/auth/session`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
Cookie: `authjs.csrf-token=${csrfToken}`,
},
body: JSON.stringify({
csrfToken: csrfToken?.split("|")[0],
user: {
name: user.nickname,
email: user.email,
image: user.profileImage,
},
}),
}
);
// console.log({ response });
}
// console.log({ session });
// redirect("/auth/social/c");
return <div>Redirecting...</div>;
}
이런 식으로 짜봤습니다.
콜백으로 jwt, session 둘 다 사용하고 있어서 체크해보았지만 post 요청을 보내도 콜백 함수에는 찍히는게 없네요
response로 찍어본 post 요청에는 200으로 성공 코드가 돌아오긴 합니다..
콘솔에 user도 잘 나오는데 session을 찍어보면 null이라고만 뜨네요..
2024. 05. 30. 10:00
며칠 간의 고생 끝에 해결했습니다..
auth.js의 구조 자체가 로그인이 인증되지 않으면 세션 값이 없으며 접근 또한 불가능하게 되어있다고 하네요..
소셜 로그인의 경우 Credentials를 통해 인증이 되지 않아 세션 데이터를 업데이트든 뭐든 할 수 없는 상황이었습니다.
제 해결 방법은 기존 아이디와 패스워드를 입력하고 진행되는 로그인 방식을 살리면서 소셜 로그인을 추가하는 방법이었기 때문에 분리가 필요했습니다.
"use client";
import { signIn, useSession } from "next-auth/react";
signIn("social-login", { redirect: false, accessToken, refreshToken, pk })
// 기존 아이디 비밀번호 입력 로그인
Credentials({
id: "default-login",
name: "DefaultLogin",
credentials: {
userIdOrEmail: {},
password: {},
},
...
})
// 소셜 로그인
Credentials({
id: "social-login",
name: "SocialLogin",
credentials: {
accessToken: { label: "Access Token", type: "text" },
refreshToken: { label: "Refresh Token", type: "text" },
pk: { label: "User PK", type: "text" },
},
...
})
이렇게 Credentials에 id를 부여하여 signIn을 진행했습니다.
이렇게 하니 const { status } = useSession();
로 출력된 status가 unauthenticated에서 정상적으로 authenticated로 변경되는 것을 확인할 수 있었습니다.
로그인이 된 상태기 때문에 session에 접근해서 데이터도 확인할 수 있었습니다!!
2024. 05. 27. 18:28
csrfToken을 추출해서 위의 링크 예시대로 요청을 보내봤습니다.
근데 jwt 콜백 함수로 넘어가지 않는 것 같네요...