如何让后端知道用户发送的访问令牌有效

时间:2019-11-03 06:06:20

标签: node.js reactjs amazon-dynamodb

我正在尝试创建一个网站用于管理员登录,以将数据添加到数据库中。实际上,当他们登录网络时,我已经为管理员编写了API。访问令牌将由jwt生成,并传递到前端并保存到用户的本地存储。我知道jwt可以添加到用户req的标头中。

但是如何让后端知道用户发送的访问令牌是有效的?

在我的数据库中,我有一个用户表,用于保存用户的电子邮件和哈希密码。当用户使用标头调用API时,后端解码访问令牌以获取用户的电子邮件并搜索数据库的好方法吗?

我的Lambda函数的这一部分,用于登录网络:

const { JWT_SECRET } = process.env
            const accessToken = jwt.sign(
              { username: event.username },
              JWT_SECRET,
              { expiresIn: '7days' }
            )

也在我的数据库中。数据结构为:

{
  'email": "***",
  "id": "*",
  "password": "***",
  "username": "***"
}

在前端,假设有一个API可以发送新数据:

export const addNewData = function (accessToken, newValue) {
  return apiClient.post(***API endpoint***',
    newValue, {
      headers: {
        Authorization: `Bearer ${accessToken}`
      }
    })

1 个答案:

答案 0 :(得分:0)

验证用户的最佳方法是使用中间件,下面是用于记录用户并使用中间件验证用户的示例代码段。

const auth = require("../middleware/auth");
const bcrypt = require("bcrypt");
const _ = require("lodash");
const { User, validate } = require("../models/user");
const express = require("express");
const router = express.Router();

router.post("/login", async (req, res) => {
  const { error } = validate(req.body);
  if (error) return res.status(400).send(error.details[0].message);

  let user = await User.findOne({ email: req.body.email });
  if (user) return res.status(400).send("User already registered.");

  user = new User(_.pick(req.body, ["name", "email", "password"]));
  const salt = await bcrypt.genSalt(10);
  user.password = await bcrypt.hash(user.password, salt);
  await user.save();

  const token = user.generateAuthToken();
  res
    .header("x-auth-token", token)
    .header("access-control-expose-headers", "x-auth-token")
    .send(_.pick(user, ["_id", "name", "email"]));
});

这是从自定义标头验证用户令牌的中间件。

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

module.exports = function(req, res, next) {
  const token = req.header("x-auth-token");
  if (!token) return res.status(401).send("Access denied. No token provided.");

  try {
    const decoded = jwt.verify(token, config.get("jwtPrivateKey"));
    req.user = decoded;
    next();
  } catch (ex) {
    res.status(400).send("Invalid token.");
  }
};

以下是在检索用户个人资料数据之前使用中间件对用户进行身份验证的代码段。

router.get("/me", auth, async (req, res) => {
  const user = await User.findById(req.user._id).select("-password");
  res.send(user);
});