NodeJS 登录后保留JWT标记

fdx2calv  于 2023-03-01  发布在  Node.js
关注(0)|答案(1)|浏览(111)

我是NodeJS的新手,所以这可能是相当低级的,但我已经尝试了这么多不同的"解决方案"在这里。
我正在使用NodeJS,MongoDB和带有VanillaJS的Express(通过Pug渲染)。我的项目遵循MVC结构。

问题

到目前为止:

  • 我可以成功登录用户,并返回正确的消息。
  • 正如我通过将其打印到控制台所检查的那样,创建了一个JWT令牌。
  • 创建JWT之后,我可以立即使用promisify访问用户:
const decode = await promisify(jwt.verify)(token, process.env.JWT_S);
   const currentAccount = await Account.findById(decode.id);
   console.log(currentAccount);
  • 但是,当我尝试运行另一个函数(例如登录成功后将数据加载到下一页)时,我无法访问此标记/它是**undefined**。

此功能的工作方式如下:

  • 页面路由包含对loadData函数的调用,该函数(目前)应该只加载用户帐户数据。
  • 此函数位于accountController.js中。
  • login函数是authController.js
  • 它调用一个createToken函数,该函数正确地创建一个令牌并返回它。
  • 退出login函数后,我无法再访问令牌,并且尝试在loadData函数中获取currentUser也不起作用,因为currentUser为**undefined**。
  • 知道它可以与Postman一起工作可能会很有用--我可以调用需要当前用户的函数。
      • 新增**在获取用户之前打印req.headers时,没有authorization字段。
      • 新增打印req.cookies.JWTundefined**。
  • 注意loadData是在页面加载时通过accountRouter调用的,这可能是有用的。这个路由器的代码没有问题。

编号
x1米17英寸1/x1米18英寸1

exports.loadData = async (req, res, next) => {
    const currentAccount = await getCurrentAccount(req);
    console.log(currentAccount) // undefined
    next();
};

x1米19英寸1/x1米20英寸1

const getCurrentAccount = async (req) => {
    let token;
    if (req.headers.authorization && req.headers.authorization.startsWith('Bearer')) {
        token = req.headers.authorization.split(' ')[1];
    } else if (req.cookies.JWT) {
        token = req.cookies.JWT;
    }

    if (token) {
        const decode = await promisify(jwt.verify)(token, process.env.JWT_S);
        const currentAccount = await Account.findById(decode.id);

        return currentAccount;
    }
    return undefined; // this is running
}

x1米21英寸1x/x1米22英寸1x

exports.login = async (req, res, next) => {
  const { email, password } = req.body;

  if (!email || !password) {
    return next(new AppError("Email and Password required.", 400));
  }

  // '+' overrides 'select: false' in the password item of accountModel
  const account = await Account.findOne({ email }).select("+password");

  if (!account || !(await account.correctPassword(password, account.password))
  ) {
    return next(new AppError("Incorrect email or password", 401));
  }

  var token = createToken(account, 200, res);

  // remove password from output
  const accountCopy = account;
  accountCopy.password = undefined;

  res.status(200).json({
    status: 'Success',
    token,
    data: {
      account: accountCopy
    }
  });
};

x1米23英寸1x/x1米24英寸1x

const createToken = (account, statusCode, res) => {
  const token = signToken(account._id);
  const cookieOptions = {
    httpOnly: true
  };

  // Send over HTTPS when the app is deployed rather than HTTP
  if (process.env.NODE_ENV === 'production') cookieOptions.secure = true;
  res.cookie('JWT', token, cookieOptions);

  return token;
};

x1米25英寸1英寸/x1米26英寸1英寸

const signToken = (id) => {
  return jwt.sign({ id }, process.env.JWT_S, {
    expiresIn: process.env.JWT_EXP,
  });
};

package.json

{
  "name": "name",
  "version": "1.0.0",
  "main": "./public/js/bundle.js",
  "dependencies": {
    "axios": "^0.27.2",
    "bcryptjs": "^2.4.3",
    "cookie-parser": "^1.4.6",
    "cors": "^2.8.5",
    "crypto": "^1.0.1",
    "dotenv": "^16.0.1",
    "express": "^4.18.1",
    "http": "^0.0.1-security",
    "https": "^1.0.0",
    "jsonwebtoken": "^9.0.0",
    "mongoose": "^6.5.3",
    "morgan": "^1.10.0",
    "node-fetch": "^3.2.10",
    "pug": "^3.0.2",
    "util": "^0.12.4"
  },
  "scripts": {
    "start": "nodemon server.js",
    "start-prod": "NODE_ENV=production nodemon server.js",
    "watch:js": "parcel watch ./public/js/index.js --out-dir --public-url ./public/js --out-file bundle.js",
    "build:js": "parcel watch ./public/js/index.js --out-dir --public-url ./public/js --out-file bundle.js"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "nodemon": "^2.0.20",
    "parcel-bundler": "^1.12.3",
    "webpack": "^5.75.0",
    "webpack-cli": "^5.0.1"
  },
  "description": ""
}

有人能帮我想想该怎么办吗?

46scxncf

46scxncf1#

您没有在login处理程序的任何地方调用createToken函数,因此json响应中的token变量是未定义的。

相关问题