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

ChangKeun Ji님의 프로필 이미지
ChangKeun Ji

작성한 질문수

[리뉴얼] React로 NodeBird SNS 만들기

카카오 로그인 적용 관련해서 질문 드릴게요

작성

·

493

0

안녕하세요 제로초님 강좌 너무 잘 들었습니다.

강의를 다 듣고난 뒤 저만의 크롬 확장 프로그램을 만들고 호스팅만 남겨놓은 상태입니다.

저는 passport 전략으로 카카오와 구글 로그인을 사용하였고 세션을 mysql에 저장하여 자동 로그인 기능을 구현했습니다.

문제는 역시 aws로 배포할 때 브라우저로 쿠키가 전달되지 않는 문제입니다. 이미 다른 분들이 질문해 주셔서 답변을 참고했습니다.

 

답변들을 참고삼아 제가 이해한 원리는 다음과 같습니다.

로그인 시도 => 백엔드에서 로그인 성공 => 카카오 콜백 라우터에서 프론트 api  라우터로 sessionId 전달 => 프론트 라우터에서 전달 받은 sessionId를 쿠키로 저장 => 홈페이지 이동 => 다시 백엔드로 get 요청 => sid 쿠키를 가지고 있기에 deserialize에서 user 정보를 req에 붙여줌 => 정상적으로 req.user 생성

 

우선 제로초님이 이곳 에서 답변하신 내용을 참고삼아서 카카오 콜백에서 프론트 라우터로 sessionId를 url로 보내주었습니다.

----------

router.get(
  "/kakao/callback",
  passport.authenticate("kakao", {
    failureRedirect: "/login",
  }),
  async (req, res) => {
      const sessionId = req.sessionID;
      const passportId = req.session.passport.user;
      res.redirect(
        `http://3.38.99.75/api/login?sid=${sessionId}&pid=${passportId}`
      );
    }
  }
);

--------

// front/api/login
export default function handler(req, res) {
  const sid = req.query.sid;
  const pid = req.query.pid;
  res.setHeader("Set-Cookie", [
    "connect.sid=" + sid + ";" + "path=/;",
    "passportId=" + pid + ";" + "path=/;",
  ]);
  res.redirect("/");
}

---------

이렇게 한 뒤 프론트에서 백엔드로 요청을 할 때 쿠키가 전달되었지만, 로그인이 되지 않습니다.

문제가 무엇인지 생각해보니 개발환경에서 보았던 값과 조금 다른것 같습니다.

개발환경에서는 SessionID값 뒤에 점이 붙은 뒤 추가 문자열이 생성되서 쿠키가 저장됩니다.

하지만 배포환경에서 제가 SessionId 값을 얻을 때는 정말 딱 session id 값만 받습니다.

로그인 후 프론트 라우터에서 홈페이지로 이동하고 그곳에서 백엔드로 보내는

첫 get 요청을 라우터로 확인하면 아래와 같습니다.

세션쿠키를 첨부해서 요청을 보내도 deserialize에서 req.user를 생성해주지 않습니다.

도저히 원인을 모르겠습니다.

 

 

이분이 해결한 방법처럼 콜백에서 passport를 호출 해보았지만 원리를 잘 모르겠고 이게 맞는 방법인지도 모르겠습니다.

-------------

router.get(
  "/kakao/callback",
  passport.authenticate("kakao", {
    failureRedirect: "/login",
  }),
  async (req, res) => {
   req.login(req.user, () => {
       req.login( req.user, () => {
} )
    })      
  }
);

-------------

 

이 문제 때문에 프로젝트 다 만들어 놓고 3일 째 끙끙 대며 호스팅을 못하고 있습니다. ㅜㅜ

왜 sessionId가 쿠키로 전달되는데도 로그인이 되지 않을까요??

 

혹시 다른 호스팅 서비스나 aws 서버리스를 사용해도 똑같은 문제가 발생할까요??

바쁘실텐데 봐주셔서 감사드립니다.

참고로 github 주소는 https://github.com/ChangKeunJi/pickle 입니다.

답변 3

0

ChangKeun Ji님의 프로필 이미지
ChangKeun Ji
질문자

 현재 하나의 인스턴스에 프론트와 백엔드 두 개를 실행시키는 작업을 시도 중인데 잘 안되고 있어

정말 죄송하게도 다시 질문드리겠습니다.

 

현재 저의 인스턴스 보안 그룹 설정은 아래와 같습니다.

 

사용자 지정 TCP를 통해서 PORT 번호를 3065로 지정해주었고, 프론트의 로그인 코드는 아래와 같습니다.

  const onClickKakao = useCallback(() => {
      Router.replace(`http://3.36.254.124:3065/login/kakao`);
  }, []);

 

백엔드 app.js 의 코드는 아래와 같습니다.

app.set("trust proxy", 1);
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(
  session({
    secret: process.env.COOKIE_SECRET,
    resave: false,
    saveUninitialized: false,
    proxy: process.env.NODE_ENV === "production",
    cookie: {
      maxAge: 315360000000, // 10년 : 1000 * 60 * 60 * 24 * 365 * 10
      httpOnly: true,
      secure: process.env.NODE_ENV === "production",
      domain: process.env.NODE_ENV === "production" && frontUrl,
    },
    store: new SequelizeStore({
      db: db.sequelize,
    }),
  })
);

app.use(passport.initialize());
app.use(passport.session());

app.use("/post", postRouter);
app.use("/login", loginRouter);
app.use("/directory", directoryRouter);

app.listen(3065, () => {
    console.log("실행 중");
  });

 

콜백 코드는 아래와 같습니다.

router.get("/kakao", passport.authenticate("kakao"));

router.get(
  "/kakao/callback",
  passport.authenticate("kakao", {
    failureRedirect: "/login",
  }),
   (req, res) => {
      res.redirect("http://3.36.254.124"); // 홈 화면으로 이동
  }
);

 

첫번째 문제는 클릭을 하면 예상한 주소 http://3.36.254.124:3065/login/kakao 가 아닌

:3065 앞에 /가 붙어서 http://3.36.254.124/:3065/login/kakao 으로 이동하여 404page가 뜹니다.

 

두번째 문제는 제가 직접 url을 http://3.36.254.124:3065/login/kakao 로 고쳐주고 로그인을 하면

백엔드에서 로그인 프로세스가 일어나지만  쿠키를 받거나 하지는 못하고 있습니다.

 

혹시 무엇이 잘못되었는지 선생님의 생각을 듣고 싶습니다.

소셜 로그인을 도저히 포기하지는 못할것 같고 JWT를 사용하면 문제가 해결될까도 궁금합니다.

바쁘실텐데 정말 감사드립니다.

 

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

Router.replace는 클라이언트 라우팅을 할 때 쓰는 겁니다. location.href = '주소'를 해야 백엔드 서버로 갑니다.

쿠키 부분은 네트워크 탭에서 쿠키 다시 확인해봐야 합니다.

0

ChangKeun Ji님의 프로필 이미지
ChangKeun Ji
질문자

그렇다면 프론트와 백엔드 두 개의 인스턴스를 만들지 않고 하나의 인스턴스에 집어넣으면 해결될까요?

작은 프로젝트라 그렇게 해도 상관 없을것 같아서요

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

네 포트만 다르게 두 개 실행하셔도 됩니다.

0

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

제가 봤을 때는 도메인 문제로 보이는데요. 프론트 서버랑 백엔드 서버랑 도메인(ip를 쓰시는 것 같습니다)이 다르지 않나요? 그러면 현실적으로 어렵습니다.

ChangKeun Ji님의 프로필 이미지
ChangKeun Ji
질문자

인스턴스 두 개 생성할 때 SSH 위치 설정 부분에서 제 IP 주소로 설정했습니다. 그게 문제가 될까요?

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

서로 다른 ip간에는 쿠키 공유가 어렵습니다.

ChangKeun Ji님의 프로필 이미지
ChangKeun Ji

작성한 질문수

질문하기