소셜 로그인 후 사용자 정보 렌더링 이슈 해결: 비동기 세션 저장

목화·2023년 4월 21일
1

서론

기록을 남기는 연습을 시작해보고자 이슈 블로깅을 작성해봅니다.

이 프로젝트에서 사용되는 기술은 NodeJS. MongoDB. ES6. Express, HTML5, CSS3, Pug 입니다.

유튜브 클론코딩(nomadcoders)을 예습하는 중 소셜로그인을 한 뒤 루트페이지로 리다이렉트 했을 때 사용자 정보가 반영되지 않는 문제가 발생했습니다. 이 과정에서 소셜로그인 후 세션을 저장하는 데 시간이 걸리고 그 과정에서 비동기처리가 필요하다는 것을 알게 되었습니다.

이슈 상황 설명

  1. 소셜로그인을 한 후 루트페이지로 리다이렉트했을 때, 화면처럼 로그인한 사용자정보가 반영되어 보여져야합니다.
  2. 그러나 사용자 정보가 담긴 쿠키는 생성되었지만, 로그인 전 페이지처럼 아무 정보도 반영되지 않은 페이지가 렌더링 되었습니다.
  3. 새로고침을 하면 그제서야 1번 스크린샷처럼 로그인 유저의 정보가 반영되었습니다.

문제 분석

  1. 로그인하지 않은 경우에도 세션 쿠키를 받아야 한다는 첫 피드백을 받았습니다. 하지만 express-sessionsaveUninitialized: false 설정에 따라 현재 단계의 코드에서는 로그인하지 않으면 쿠키를 초기화하지 않기 때문에 브라우저와 서버 모두 쿠키를 따로 저장하지 않았습니다. (세션에 대한 정보는 존재합니다.)
// server.js
// ...
app.use(
  session({
    secret: process.env.COOKIE_SECRET,
    resave: false,
    saveUninitialized: false, // 해당 옵션
    store: MongoStore.create({ mongoUrl: process.env.DB_URL }),
  }),
);
// ...

saveUninitialized

Forces a session that is “uninitialized” to be saved to the store. A session is uninitialized when it is new but not modified. Choosing false is useful for implementing login sessions, reducing server storage usage, or complying with laws that require permission before setting a cookie. Choosing false will also help with race conditions where a client makes multiple parallel requests without a session.

The default value is true, but using the default has been deprecated, as the default will change in the future. Please research into this setting and choose what is appropriate to your use-case.

Note if you are using Session in conjunction with PassportJS, Passport will add an empty Passport object to the session for use after a user is authenticated, which will be treated as a modification to the session, causing it to be saved. This has been fixed in PassportJS 0.3.0

  1. 니꼬쌤이 세션 정보가 저장되기 전에 리다이렉트가 발생하기 때문일 것이라는 피드백을 주었습니다. 세션 정보를 저장하는 데 시간이 필요하기 때문에 이를 기다렸다가 리다이렉트해야 한다고 합니다. 소셜로그인 후 사용자 정보가 담긴 쿠키는 존재하지만 렌더링페이지에서 반영이 안 된 것으로 보아 이것이 원인일 것으로 판단됩니다.

해결 방법

이 문제를 해결하기 위해 니꼬쌤의 피드백에 따라 finishGithubLogin 함수에서 아래와 같이 await req.session.save()를 사용하여 세션 정보를 저장한 후 리다이렉트를 하도록 수정했습니다.

// userController.js
// ...
let user = await User.findOne({ email: emailObj.email });
if (!user) {
  user = await User.create({
    // ...
  });
}
req.session.loggedIn = true;
req.session.user = user;
await req.session.save(); // 해당 부분
return res.redirect('/');
// ...

간단하게 저 코드 한 줄을 추가함으로써 문제를 해결할 수 있었습니다.

결론

문제의 원인은 세션 정보가 저장되기 전에 리다이렉트가 발생했기 때문이었습니다. 이를 해결하기 위해 await req.session.save()를 사용하여 세션 정보를 저장한 후 리다이렉트를 하도록 코드를 수정했습니다. 결과적으로 사용자 정보가 정상적으로 반영되어 페이지에 표시되었습니다.

참고자료

profile
🧑‍💻 SOFTWARE ENGINEER. 무해를 지향합니다. 편견을 지양합니다.

0개의 댓글