[내배캠] TIL, WIL/TIL

로그인 문제

값싼외노자 2022. 12. 23. 01:11
const jwt = require("jsonwebtoken");
const { User } = require("../models");

module.exports = (req, res, next) => {
  console.log(req.headers);
  
  const { cookie } = req.headers;
  const [authType, authToken] = (cookie || "").split("=");

  if (!authToken || authType !== "token") {
    res.status(401).send({
      errorMessage: "로그인 후 이용 가능한 기능입니다.",
    });
    return;
  }

  try {
    const { userId } = jwt.verify(authToken, "customized-secret-key");
    User.findByPk(userId).then((user) => {
      res.locals.user = user
      next();
    });
  } catch (err) {
    res.status(401).send({
      errorMessage: "로그인 후 이용 가능한 기능입니다.",
    });
  }
};

// auth-middleware

 

2주차 개인 과제 중 로그인 기능 관련하여 해당 코드를 구현하다 에러를 발견하였는데,

 

썬더 클라이언트

Executing (default): SELECT `userId`, `nickname`, `password`, `createdAt`, `updatedAt` FROM `Users` AS `User` WHERE `User`.`nickname` = 'gkswngh123';
{
  'content-length': '76',
  'accept-encoding': 'gzip, deflate, br',
  cookie: 'token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjQsImlhdCI6MTY3MTcwNDUyMX0.GgzUQTPByrttjnA-HHr3_jPQIQ2_-EKnUeSIvpLFLt0',
  accept: '*/*',
  'user-agent': 'Thunder Client (https://www.thunderclient.com)',
  'content-type': 'application/json',
  host: 'localhost:8080',
  connection: 'close'
}
Executing (default): SELECT `userId`, `nickname`, `password`, `createdAt`, `updatedAt` FROM `Users` AS `User` WHERE `User`.`userId` = 4;
Executing (default): INSERT INTO `Posts` (`postId`,`title`,`content`,`createdAt`,`updatedAt`,`userId`) VALUES (DEFAULT,?,?,?,?,?);
node:internal/process/promises:288
            triggerUncaughtException(err, true /* fromPromise */);
            ^

Error
    at Query.run (C:\Users\jh\Desktop\연습\2week_prac\node_modules\sequelize\lib\dialects\mysql\query.js:52:25)
    at C:\Users\jh\Desktop\연습\2week_prac\node_modules\sequelize\lib\sequelize.js:314:28
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async MySQLQueryInterface.insert (C:\Users\jh\Desktop\연습\2week_prac\node_modules\sequelize\lib\dialects\abstract\query-interface.js:308:21)
    at async Post.save (C:\Users\jh\Desktop\연습\2week_prac\node_modules\sequelize\lib\model.js:2432:35)
    at async Post.create (C:\Users\jh\Desktop\연습\2week_prac\node_modules\sequelize\lib\model.js:1344:12)
    at async C:\Users\jh\Desktop\연습\2week_prac\routes\post.js:34:5 {
  name: 'SequelizeForeignKeyConstraintError',
  parent: Error: Cannot add or update a child row: a foreign key constraint fails (`2week_blog`.`Posts`, CONSTRAINT `Users_Posts_id_fk` FOREIGN KEY (`userId`) REFERENCES `Users` (`userId`) ON DELETE CASCADE ON UPDATE CASCADE)       
      at Packet.asError (C:\Users\jh\Desktop\연습\2week_prac\node_modules\mysql2\lib\packets\packet.js:728:17)
      at Execute.execute (C:\Users\jh\Desktop\연습\2week_prac\node_modules\mysql2\lib\commands\command.js:29:26)
      at Connection.handlePacket (C:\Users\jh\Desktop\연습\2week_prac\node_modules\mysql2\lib\connection.js:456:32)
      at PacketParser.onPacket (C:\Users\jh\Desktop\연습\2week_prac\node_modules\mysql2\lib\connection.js:85:12)
      at PacketParser.executeStart (C:\Users\jh\Desktop\연습\2week_prac\node_modules\mysql2\lib\packet_parser.js:75:16)
      at Socket.<anonymous> (C:\Users\jh\Desktop\연습\2week_prac\node_modules\mysql2\lib\connection.js:92:25)
      at Socket.emit (node:events:513:28)
      at addChunk (node:internal/streams/readable:324:12)
      at readableAddChunk (node:internal/streams/readable:297:9)
      at Readable.push (node:internal/streams/readable:234:10) {
    code: 'ER_NO_REFERENCED_ROW_2',
    errno: 1452,
    sqlState: '23000',
    sqlMessage: 'Cannot add or update a child row: a foreign key constraint fails (`2week_blog`.`Posts`, CONSTRAINT `Users_Posts_id_fk` FOREIGN KEY (`userId`) REFERENCES `Users` (`userId`) ON DELETE CASCADE ON UPDATE CASCADE)',     
    sql: 'INSERT INTO `Posts` (`postId`,`title`,`content`,`createdAt`,`updatedAt`,`userId`) VALUES (DEFAULT,?,?,?,?,?);',
    parameters: [
      '콜라 마시고 싶당',
      '근데 돈이없넹..',
      '2022-12-22 10:22:03',
      '2022-12-22 10:22:03',
      '[object SequelizeInstance:User]'
    ]
  },
  original: Error: Cannot add or update a child row: a foreign key constraint fails (`2week_blog`.`Posts`, CONSTRAINT `Users_Posts_id_fk` FOREIGN KEY (`userId`) REFERENCES `Users` (`userId`) ON DELETE CASCADE ON UPDATE CASCADE)     
      at Packet.asError (C:\Users\jh\Desktop\연습\2week_prac\node_modules\mysql2\lib\packets\packet.js:728:17)
      at Execute.execute (C:\Users\jh\Desktop\연습\2week_prac\node_modules\mysql2\lib\commands\command.js:29:26)
      at Connection.handlePacket (C:\Users\jh\Desktop\연습\2week_prac\node_modules\mysql2\lib\connection.js:456:32)
      at PacketParser.onPacket (C:\Users\jh\Desktop\연습\2week_prac\node_modules\mysql2\lib\connection.js:85:12)
      at PacketParser.executeStart (C:\Users\jh\Desktop\연습\2week_prac\node_modules\mysql2\lib\packet_parser.js:75:16)
      at Socket.<anonymous> (C:\Users\jh\Desktop\연습\2week_prac\node_modules\mysql2\lib\connection.js:92:25)
      at Socket.emit (node:events:513:28)
      at addChunk (node:internal/streams/readable:324:12)
      at readableAddChunk (node:internal/streams/readable:297:9)
      at Readable.push (node:internal/streams/readable:234:10) {
    code: 'ER_NO_REFERENCED_ROW_2',
    errno: 1452,
    sqlState: '23000',
    sqlMessage: 'Cannot add or update a child row: a foreign key constraint fails (`2week_blog`.`Posts`, CONSTRAINT `Users_Posts_id_fk` FOREIGN KEY (`userId`) REFERENCES `Users` (`userId`) ON DELETE CASCADE ON UPDATE CASCADE)',     
    sql: 'INSERT INTO `Posts` (`postId`,`title`,`content`,`createdAt`,`updatedAt`,`userId`) VALUES (DEFAULT,?,?,?,?,?);',
    parameters: [
      '콜라 마시고 싶당',
      '근데 돈이없넹..',
      '2022-12-22 10:22:03',
      '2022-12-22 10:22:03',
      '[object SequelizeInstance:User]'
    ]
  },
  sql: 'INSERT INTO `Posts` (`postId`,`title`,`content`,`createdAt`,`updatedAt`,`userId`) VALUES (DEFAULT,?,?,?,?,?);',
  parameters: [
    '콜라 마시고 싶당',
    '근데 돈이없넹..',
    '2022-12-22 10:22:03',
    '2022-12-22 10:22:03',
    '[object SequelizeInstance:User]'
  ],
  table: 'Users',
  fields: [ 'userId' ],
  value: User {
    dataValues: {
      userId: 4,
      nickname: 'gkswngh123',
      password: '1234',
      createdAt: 2022-12-22T07:09:40.000Z,
      updatedAt: 2022-12-22T07:09:40.000Z
    },
    _previousDataValues: {
      userId: 4,
      nickname: 'gkswngh123',
      password: '1234',
      createdAt: 2022-12-22T07:09:40.000Z,
      updatedAt: 2022-12-22T07:09:40.000Z
    },
    uniqno: 1,
    _changed: Set(0) {},
    _options: {
      isNewRecord: false,
      _schema: null,
      _schemaDelimiter: '',
      raw: true,
      attributes: [ 'userId', 'nickname', 'password', 'createdAt', 'updatedAt' ]
    },
    isNewRecord: false
  },
  index: 'Users_Posts_id_fk',
  reltype: 'child'
}

Node.js v18.12.1
PS C:\Users\jh\Desktop\연습\2week_prac>

 

이러한 에러 코드를 보아도 문제를 확인하기가 어려웠다.

 

그래서 나는 routes/user.js 에 있는 로그인 관련 코드를 수정하였는데도,

router.post("/auth", async (req, res) => { 
    const { nickname, password } = req.body;
  
    const user = await User.findOne({
      where: { nickname:nickname },
    });
  
    // NOTE: 인증 메세지는 자세히 설명하지 않는것을 원칙으로 한다: https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html#authentication-responses
    if (!user || password !== user.password) {
      res.status(400).send({
        errorMessage: "닉네임 또는 패스워드가 틀렸습니다.",
      });
      return;
    };
    const token = jwt.sign({ userId: user.userId }, "customized-secret-key");
    res.cookie('token', token);

    res.json({token:token})

  });

const token 부분을 고치고 뒤에 쿠키가 제대로 들어오는지 콘솔.로그 찍어봤는데 우선 쿠키는 정상적으로

들어오는 것이 확인되었다.

 

혹시 하는 마음에, 다시 로그인 미들 웨어 쪽을 살펴 보았는데,

res.locals.user 부분에 뒤에 userId만 따로 등록하면 어떨까 하는 생각이 들어 해당 코드로 수정하고 결과를 확인헀다

const jwt = require("jsonwebtoken");
const { User } = require("../models");

module.exports = (req, res, next) => {
  console.log(req.headers);
  
  const { cookie } = req.headers;
  const [authType, authToken] = (cookie || "").split("=");

  if (!authToken || authType !== "token") {
    res.status(401).send({
      errorMessage: "로그인 후 이용 가능한 기능입니다.",
    });
    return;
  }

  try {
    const { userId } = jwt.verify(authToken, "customized-secret-key");
    User.findByPk(userId).then((user) => {
      res.locals.user = user.userId; // 유저 부분 
      next();
    });
  } catch (err) {
    res.status(401).send({
      errorMessage: "로그인 후 이용 가능한 기능입니다.",
    });
  }
};

결과는

성공!

아무래도 쿠키 부분을 처리하면서 userId를 제대로 지칭하지 않아 생긴 오류인 것으로 확인된다.

다행스럽게 로그인이 정상적으로 처리되면서 구현해놓은 기능들이 정상적으로 작동하는 것을 끝으로 오늘 TIL을 마친다.

'[내배캠] TIL, WIL > TIL' 카테고리의 다른 글

노드JS 프리티어  (1) 2022.12.26
노드JS 스웨거  (0) 2022.12.26
노드js  (0) 2022.12.22
자바 스크립트  (0) 2022.12.21
자바 스크립트  (0) 2022.12.19