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

JaeChul Lee님의 프로필 이미지

작성한 질문수

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

도메인 연결하기

프로필 페이지에서 401 에러가납니다 ㅜㅜ

작성

·

1.1K

0

로그인 후 프로필 페이지로 가면 401 에러가 납니다.

배포후에만 발생하는 문제이며 로컬에서는 잘 작동합니다.

back서버에서 /user/followers 라우터에서

isLoggedIn 을 체크하는데 여기서

req.isAuthenticated() 가 false 가 되어

로그인이 필요합니다 라는 메세지가 브라우저로 전달됩니다.

(Network 탭에 followers 클릭후 Response 택 클릭시

로그인이 필요합니다 라고 표시됩니다)

(물론 followings 도 마찬가지입나다)

이때는 로그인이 풀려보이지는 않는데

다시 Home 으로 가보면 로그인이 풀려있습니다.

ㅁ followers 혹은 followings 요청 401 에러

귀찮게 안해드리려고 혼자서 어떻게든 해보려 했는데

도저히 어떻게 수정해야 할지도 모르겠네요 ㅜㅜ

답변 12

1

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

getServerSideProps의 로그는 프론트 서버에서만 보입니다. pm2 logs --lines 100 이 명령어로 확인 가능합니다.

새로고침 시 로그인이 풀리는 문제는 쿠키 문제가 맞습니다. cookie 로그를 확인해보세요.

0

안녕하세요 저도 도움점 받고 싶어서요.. 비슷한 문제인거 같은데요.. reducer 핸들러 리팩토링한 부분 어디 위치가 문제였나요?

0

JaeChul Lee님의 프로필 이미지
JaeChul Lee
질문자

수정했습니다~~!!!! 장장 6시간이 걸렸네요 ㅜㅜ

제로초님이 중간중간 계속 봐주셔서 힘을 낼 수 있었습니다.

최종원인은 제가 reducer 핸들러 리팩토링한 부분에 있었습니다.

정말 감사합니다~!!!

0

JaeChul Lee님의 프로필 이미지
JaeChul Lee
질문자

지금해보니 로컬에서도 풀리네여~ 와우

로컬에서 로그인후 F5 누르면 풀려버리고요

그 상태에서 프로필로 가면 또 로그인이 되어 있습니다.

그 다음부터는 F5 눌러도 안풀리고여.

제가 뭔가 실수한 부분이 있는것 같습니다.

0

JaeChul Lee님의 프로필 이미지
JaeChul Lee
질문자

앗, 이 늦은시간까지 신경써주셔서 정말 감사힙니다~!

Send 로 보내던 부분 전부 axios 로 바꿨습니다.

혹시 front 서버에 build 폴더에 Send 의 흔적이 남아서 그런건가 싶어서 build 한걸 싹 초기화하고 다시 build 하고 싶은데 어떻게 하는줄 몰라서 그냥 npm run build 하고 재시작만 한 상태입니다. ㅜㅜ

저도 일단 의심되는게  Send 여서 로그인사용자 정보 가져오는 부분만 axios 를 써서 

axios.get("http://api.webcenter.one/user") 라고 바꿔서 해봤더니 로그인이 안풀리더라고요.

그래서 Send 부분 다 빼고 axios 로 바꾸고 나니 다시 로그인 풀리는 문제가 발생하더라구여 ㅜㅜ

- sagas/index.js 입니다.

import user from './user';
import post from './post';
import { combineReducers } from 'redux';
import { HYDRATE } from 'next-redux-wrapper';
import { userSaga } from './user';
import { postSaga } from './post';
import { all } from 'redux-saga/effects';
import axios from 'axios';
import { backUrl } from '../config/config';

axios.defaults.baseURL = backUrl;
axios.defaults.withCredentials = true;

const rootReducer = (state, action) => {
   switch (action.type) {
      case HYDRATE:
         console.log('HYDRATE', action);
         return action.payload;
      default:
         const combinedReducer = combineReducers({
            user,
            post,
         });
         return combinedReducer(state, action);
   }
};

export function* rootSaga() {
   yield all([userSaga(), postSaga()]);
}

export default rootReducer;

0

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

전체적으로 Send를 사용해서 보내시는게 맞죠? axios.defaults에 쿠키를 설정하는데 Send에는 설정이 안되는것같은 의심이드네요

0

JaeChul Lee님의 프로필 이미지
JaeChul Lee
질문자

아참, getServerSideProps 에 cookie 값도 찍히게 해놨는데

크롬 개발자도구에서 log 가 안보이네요.

pm2 모니터에선 스크롤이 안내려가서 확인이 안되구요

ㅜㅜ

export const getServerSideProps = wrapper.getServerSideProps(async context => {

   const cookie = context.req ? context.req.headers.cookie : '';
   console.log('######### in ServerSideProps, cookie=', cookie);
   axios.defaults.headers.Cookie = '';
   if (context.req && cookie) {
      axios.defaults.headers.Cookie = cookie;
   }
   context.store.dispatch(loadUserSessionAction());
   context.store.dispatch(loadPostsAction());
   context.store.dispatch(END);
   await context.store.sagaTask.toPromise();
});

export default Home;

0

JaeChul Lee님의 프로필 이미지
JaeChul Lee
질문자

npx pm2 monit 돌려놓고 

로그인 후 req.user 세팅되구 있구여

F5 로 화면갱신하면 로그인이 풀려버리고

로그 확인하면 아래와 같이 req.user 가 undefined 로 되어있어요

로그 찍은부분 코드입니다.

router.get("/", async (req, res, next) => {
  try {
    console.log(":::::::: Load Session, req.user=", req.user);
    if (req.user) {
      const fullUser = await users.findOne({
        where: { id: req.user.id },
        attributes: {
          exclude: ["password"],
        },
        include: [
          { model: posts, as: "posts", attributes: ["id"] }, // 브라우저에서 user.posts 에 post 의 모든 정보가 담겨있으면 메모리 낭비가 발생하므로 id 만 보낸다.
          { model: users, as: "followings", attributes: ["id"] },
          { model: users, as: "followers", attributes: ["id"] },
        ],
      });
      res.status(200).json(fullUser);
    } else {
      res.status(200).json(null);
    }
  } catch (e) {
    next(e);
  }
});

0

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

이건 프론트에서 서버사이드랜더링 문제같습니다. 새로고침을 해도 로그인이 계속 풀려있나요? 일단 서버사이드렌더링 잘 안되는 문제도 쿠키 문제는 맞습니다.

getServerSideProps에서 console.log cookie 하셔서 브라우저의 쿠키가 프론트 서버쪽에서도 동일하게 뜨는지 확인해봐야할것같습니다. 그리고 백엔드에서는 req.user가 생기는지도요.

0

JaeChul Lee님의 프로필 이미지
JaeChul Lee
질문자

휴일중에 답변도 달아주시고 정말 감사합니다~

근데 문제가 바꼈어요~

크롬 캐시 다 날리고 다시 접속해보니 프로필로 갔을대

401 문제는 사라졌습니다. ㄷㄷ;;

근데 프로필에서 다시 홈으로 가면 로그인이 풀려있고

다시 로그인하려고 하면 "로그인하지 않은 사용자만 접근가능합니다" 메세지가 뜹니다 ㅜㅜ

0

JaeChul Lee님의 프로필 이미지
JaeChul Lee
질문자

네 둘다 해줬어요~

- axios 는 Send.js 로 만들어서 사용중입니다.

const Send = axios.create({
   baseURL: backUrl,
   withCredentials: true,
});
export default Send;

- app.js 

app.use(
  session({
    saveUninitialized: false,
    resave: false,
    secret: process.env.COOKIE_SECRET,
    cookie: {
      httpOnly: true,
      secure: false, 
      domain: prod && ".xxx.com",
    },
  })
);

- package.json 

"scripts": {
    "dev": "nodemon app",
    "start": "cross-env NODE_ENV=production pm2 start app.js"
  },

위와 같이 되어있습니다~

Network 탭에서 login 리퀘스트 찍어보면

Set-Cookie 헤더도 있고,

Application 탭에서 Cookies 에 connect.sid 쿠키도

들어와있습니다 

0

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

쿠키 문제 같은데요. 프론트에서 withCredentials true는 하셨죠? 백엔드 express session 미들웨어에서 cookie 도메인에 .webcenter.one 넣으셨나요?