【问题标题】:How to save a token in a local storage (or cookie)?如何将令牌保存在本地存储(或 cookie)中?
【发布时间】:2019-10-26 13:16:10
【问题描述】:

我正在尝试在应用程序中实现登录功能。目前,我可以注册一个登录名,生成一个 jwt 令牌。但是,我不知道如何将此令牌存储在 cookie(或本地存储)中。我有一个中间件,需要用户在每个私有请求中发送一个令牌。在邮递员中,我可以将“x-auth-token”和一个令牌放在标题中。许多教程使用了护照、cookie-parser,这看起来有点复杂。还有其他更简单的方法吗?我在快递文档中看到也有res.cookie('x-auth-token', token); 可用,我试过了,但没有用。我也试过window.localStorage.setItem('x-auth-token', token);,还是不行。

我尝试了一些超级简单的方法,即简单地将令牌放入 localStorage。 window.localStorage.setItem('x-auth token', token); 但是没用。

授权

const jwt = require('jsonwebtoken');
const config = require('config');

// middleware function, next so it moves on to the next middlware
module.exports = function(req, res, next) {
  //get the token from header
  const token = req.header('x-auth-token');

  //Check if not token
  if (!token) {
    return res.status(401).json({ msg: 'No token, authorization denied' });
  }

  //Verify token if exist
  try {
    const decoded = jwt.verify(token, config.get('jwtSecret'));
    req.user = decoded.user;
    next();
  } catch (err) {
    res.status(401).json({ msg: 'Token is not valid' });
  }
};

posts.js

// @ route    POST api/users
// @desc      Register User
// @access    Public
router.post(
  '/',
  [
    check('name', 'Name is required')
      .not()
      .isEmpty(),
    check('email', 'Please include a valid email').isEmail(),
    check(
      'password',
      ' Please enter a password with 6 or more characters'
    ).isLength({ min: 6 })
  ],
  async (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({
        errors: errors.array()
      });
    }
    const { name, email, password } = req.body;

    try {
      // See if user exists, have to be unique
      let user = await User.findOne({ email });
      if (user) {
        return res
          .status(400)
          .json({ errors: [{ msg: 'User already exists' }] });
      }
      // Get users gravatar
      const avatar = gravatar.url(email, {
        s: '200',
        r: 'pg',
        d: 'mm'
      });
      user = new User({
        name,
        email,
        avatar,
        password
      });

      //encrypt password
      const salt = await bcrypt.genSalt(10);

      user.password = await bcrypt.hash(password, salt);
      // anything that return a promise, we have to put await !!
      await user.save();
      //return jsonwebtoken
      const payload = {
        user: {
          id: user.id
        }
      };

      jwt.sign(
        payload,
        config.get('jwtSecret'),
        { expiresIn: 60 * 60 * 100 },
        (err, token) => {
          // window.localStorage.setItem('x-auth-token', token);
          res.json({ token });
          res.cookie('x-auth-token', token);
          // req.flash('You seccessfully registered your account');
          // res.redirect('/user/login');
        }
      );
    } catch (err) {
      console.error(err.message);
      res.status(500).send('Server error');
    }
  }
);

main.handlebars

<!DOCTYPE html>
<html lang="en">

<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="/css/main.css">
    <link rel="stylesheet" href="/css/register.css">
    <link href="https://fonts.googleapis.com/css?family=Roboto&display=swap" rel="stylesheet">
    <script src="https://use.fontawesome.com/804afe4c6e.js"></script>

    {{!-- for auto-reload --}}
    <script src="/reload/reload.js"></script>
    <script src="/javascript/main.js"></script>


    <title>Idea Share</title>
</head>

<body>

    <nav class="navbar bg-dark">
        <h1><a href="/">Idea Share</a></h1>
        <ul>
            <a href="/signup">
                <li>Sign up</li>
            </a>
            <a href="/signup">
                <li>Log in</li>
            </a>
        </ul>
    </nav>
    <div class="container">
        {{{body}}}
    </div>
</body>

</html>

register.handlebars

<div class="height-container">
    <div class="vertical-align">
        <div class="register-form">
            <h1>Create your account</h1>
            <form class="form" action="/api/users" method="post">
                <div class="form-group">
                    <input name="name" type="text" placeholder="Name" requried>
                </div>

                <div class="form-group">
                    <input name="email" type="email" placeholder="E-mail">
                </div>  

                <div class="form-group">
                    <input name="password" type="text" placeholder="Password" minlength="6">
                </div>
                <input onclick="loginUser()" type="submit" value="Create account" class="button green-button" />
            </form>
            <p>Already have an account? <a href="/signin">Sign in</a></p>
        </div>
    </div>
</div>

post.handlebars

<div class="height-container">
    <div class="vertical-align">
        <div class="idea-form">
            <h1>Share your idea</h1>
            <form class="form" action="/api/posts" method="post">
                <div class="form-group">
                    <input type="text" placeholder="What is your idea?" name="title" requried>
                </div>

                <div class="form-group">
                    <input type="text" placeholder="Let us know more detail. What is the story. How did you come up with it? 
Why do you think people would need it etc" name="body">
                </div>
                <input "type=" submit" value="Post" class="button green-button" />

            </form>
        </div>
    </div>
</div>

【问题讨论】:

  • 你在节点JS上执行上面的代码。节点没有 windows 对象。 localStorage 在 window 对象中定义。您必须从客户端设置令牌。
  • 如果你想在 cookie 中存储令牌,那么你可以从 nodejs 中设置它

标签: node.js express jwt express-jwt


【解决方案1】:

您不能将项目保存到 nodejs 中的本地存储。首先将您的响应发送到客户端,然后使用 localStorage.setItem('x-auth-token', token); 将 res 令牌保存到浏览器本地存储。

在客户端使用您的令牌:-

http.post('/', userCredentials).then(response => {
    window.localStorage.setItem('x-auth-token', response.token)
  }
  );

【讨论】:

  • 谢谢你的回答,但你能更清楚地解释一下吗?我尝试制作一个提交按钮来触发包含您上面的代码但得到Reference Error: http is not defined 的事件处理程序。在表单中的注册提交按钮上,我输入了 &lt;input onclick="loginUser()" type="submit" value="Create account" class="button green-button" /&gt; 。然后对于 main.js(客户端 javascript),我添加了您的代码,例如 function loginUser() { http.post('/', userCredentials).then(response =&gt; { window.localStorage.setItem('x-auth-token', response.token); }); }
  • 你能用更多的客户端代码更新这个问题吗?你还在使用任何客户端框架吗?
  • 当然,我会更新它。客户端框架?我正在使用车把,是其中之一吗?
  • 我没有用过车把,但尝试在脚本中包含这个var http = require('http');
  • 脚本?你的意思是前端脚本?但不需要节点语法吗?
猜你喜欢
  • 2021-10-08
  • 2019-06-12
  • 2017-09-22
  • 2018-11-12
  • 2020-07-04
  • 1970-01-01
  • 2017-02-11
  • 2018-02-18
  • 2016-01-19
相关资源
最近更新 更多