inflearn logo
강의

Course

Instructor

[Renewal] Creating a NodeBird SNS with React

Cookies/sessions and overall login flow.

로그인시 401 Unauthorized 오류가 뜹니다

90

tlgjawl01304528

2 asked

0

 

image.png

로그인시 401 Unauthorized 오류가 떠서

image.png

리덕스 액션을 봤더니 LOG_IN_FAILURE에 error 내용이 비어 있었습니다.

routes/user.js

const express = require("express");
const bcrypt = require("bcrypt");
const { User, Post } = require("../models");
const passport = require("passport");

const router = express.Router();

router.post("/login", (req, res, next) => {
  console.log("🧾 req.body:", req.body);
  passport.authenticate("local", (err, user, info) => {
    if (err) {
      console.error(err);
      return next(err);
    }
    if (info) {
      return res.status(401).send(info.reason);
    }
    return req.login(user, async (loginerr) => {
      if (loginerr) {
        console.error(loginerr);
        return next(loginerr);
      }
      const fullUserWithoutPassword = await User.findOne({
        where: { id: user.id },
        attributes: {
          exclude: ["password"],
        },
        include: [
          {
            model: Post,
          },
          {
            model: User,
            as: "Followings",
          },
          {
            model: User,
            as: "Followers",
          },
        ],
      });
      return res.status(200).json(fullUserWithoutPassword);
    });
  })(req, res, next);
});

router.post("/", async (req, res, next) => {
  try {
    const exUser = await User.findOne({
      where: {
        email: req.body.email,
      },
    });
    if (exUser) {
      return res.status(403).send("이미 사용중인 아이디입니다.");
    }
    const hashedPassword = await bcrypt.hash(req.body.password, 12);
    await User.create({
      email: req.body.email,
      nickname: req.body.nickname,
      password: hashedPassword,
    });
    res.status(201).send("ok");
  } catch (error) {
    console.error(error);
    next(error);
  }
});

module.exports = router;

세션 쿠키가 잘 전달이 안된건가 싶어서 req.body를 서버 터미널로 찍었더니
req.body: undefined 로 나왔습니다.

로그인 폼에서 데이터를 잘못 넘겨준건가 해서 확인해봤더니
loginForm.js

  const onSubmitForm = useCallback(() => {
    console.log(email, password);
    dispatch(loginRequestAction({ email, password }));
  }, [email, password]);

데이터도 잘 넘겨준 것 같고

sagas/user.js

function logInAPI(data) {
  return axios.post("/user/login", data);
}

function* logIn(action) {
  try {
    const result = yield call(logInAPI, action.data);
    yield put({
      type: LOG_IN_SUCCESS,
      data: result.data,
    });
  } catch (err) {
    console.error(err);
    yield put({
      type: LOG_IN_FAILURE,
      error: err.response.data,
    });
  }
}

사가쪽도 문제가 없어보여서 프론트 쪽 문제는 아닌 것 같고 백엔드쪽 문제 같은데 도저히 어디서 문제가 생긴건지 모르겠습니다.

app.js

const express = require("express");
const cors = require("cors");
const session = require("express-session");
const cookieParser = require("cookie-parser");
const postRouter = require("./routes/post");
const userRouter = require("./routes/user");
const db = require("./models");
const passportConfig = require("./passport");
const passport = require("passport");
const dotenv = require("dotenv");

dotenv.config();
const app = express();

db.sequelize
  .sync()
  .then(() => {
    console.log("db 연결성공");
  })
  .catch(console.error);
passportConfig();
app.use(
  cors({
    origin: "*",
    credentials: false,
  })
);
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser(process.env.COOKIE_SECRET));
app.use(
  session({
    saveUninitialized: false,
    resave: false,
    secret: process.env.COOKIE_SECRET,
  })
);
app.use(passport.initialize());
app.use(passport.session());

app.get("/", (req, res) => {
  res.send("hello express");
});

app.get("/api", (req, res) => {
  res.json([
    {
      id: 1,
      content: "hello",
    },
    {
      id: 2,
      content: "hello2",
    },
    {
      id: 3,
      content: "hello3",
    },
  ]);
});

app.get("/api/posts", (req, res) => {
  res.json([
    {
      id: 1,
      content: "hello",
    },
    {
      id: 2,
      content: "hello2",
    },
    {
      id: 3,
      content: "hello3",
    },
  ]);
});

app.use("/post", postRouter);
app.use("/user", userRouter);

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


passport/local.js

const passport = require("passport");
const { Strategy: LocalStrategy } = require("passport-local");
const { User } = require("../models");
const bcrypt = require("bcrypt");

module.exports = () => {
  passport.use(
    new LocalStrategy(
      {
        usernameField: "email",
        passwordField: "password",
      },
      async (email, password, done) => {
        try {
          console.log("입력값:", email, password);
          const user = await User.findOne({
            where: { email },
          });
          console.log("찾은 유저:", user && user.email);
          if (!user) {
            return done(null, false, { reason: "존재하지 않는 이메일입니다!" });
          }
          const result = await bcrypt.compare(password, user.password);
          if (result) {
            return done(null, user);
          }
          return done(null, false, { reason: "비밀번호가 틀렸습니다." });
        } catch (error) {
          console.log(error);
          return done(error);
        }
      }
    )
  );
};


passport/index.js

const passport = require("passport");
const local = require("./local");
const { User } = require("../models");

module.exports = () => {
  passport.serializeUser((user, done) => {
    done(null, user.id);
  });

  passport.deserializeUser(async (id, done) => {
    try {
      const user = await User.findOne({ where: { id } });
      done(null, user);
    } catch (error) {
      console.error(error);
      done(error);
    }
  });

  local();
};


백엔드 코드를 첨부하였습니다.

image.png


터미널에 나온 콘솔 내용입니다.
local.js파일에서도 콘솔("입력값:","찾은 유저:" )을 찍었는데 터미널에 찍힌 콘솔은 req.body만 찍혔습니다..

react redux node.js express next.js

Answer 1

0

zerocho

개발자도구 네트워크탭쪽에서 확인을 하면 프론트문제인지 백엔드 문제인지 좀 더 알기 쉬워집니다.

네트워크탭에 POST /user/login 요청을 찾아서 payload 부분에 데이터가 들어있는지 확인해보세요. 들어있다면 백엔드쪽 문제이고 안 들어있으면 프론트 문제입니다.

넥스트 버젼 질문

0

78

2

무한 스크롤 중 스크롤 튐 현상

0

177

1

특정 페이지 접근을 막고 싶을 때

0

103

2

createGlobalStyle의 위치와 영향범위

0

97

2

인라인 스타일 리렌더링 관련

0

92

2

vsc 에서 npm init 설치시 오류

0

148

2

nextjs 15버전 사용 가능할까요?

0

160

1

화면 새로고침 문의

0

123

1

RTK에서 draft, state 차이가 있나요?

0

154

2

Next 14 사용해도 될까요?

0

452

1

next, node 버전 / 폴더 구조 질문 드립니다.

0

349

1

url 오류 질문있습니다

0

211

1

ssh xxxxx로 우분투에 들어가려니까 port 22: Connection timed out

0

375

1

sudo certbot --nginx 에러

0

1281

2

Minified React error 콘솔에러 (hydrate)

0

470

1

카카오 공유했을 때 이전에 작성했던 글이 나오는 버그

0

247

1

프론트서버 배포 후 EADDRINUSE에러 발생

0

329

1

npm run build 에러

0

519

1

front 서버 npm run build 중에 발생한 에러들

0

383

1

서버 실행하고 브라우저로 들어갔을때 404에러

0

338

2

css 서버사이드 랜더링이 적용되지 않아서 문의 드립니다.

0

289

1

팔로워 3명씩 불러오고 데이터 합쳐주는걸로 바꾸고 서버요청을 무한으로하고있습니다.

0

240

2

해시태그 검색에서 throttle에 관해 질문있습니다.

0

202

1

full reload 될때는 서버 데이터를 호출하는데 그 이후로 새로고침할대는 호출하지 않아서 답답합니다

0

293

2