【问题标题】:Bearer token undefined(Authentication)承载令牌未定义(身份验证)
【发布时间】:2022-01-23 07:52:46
【问题描述】:

我在我的 mern stack 项目中使用 jwt 身份验证。注册工作正常,但每当我尝试登录时,我都会在控制台中收到此消息:

message: "Success"
token: "Bearer undefined"

这是我的 server.js 代码,后面包含身份验证 API:

app.post("/register", async (req, res) => {
  const user = req.body;

  const takenEmail = await User.findOne({email: user.email})
  
  if(takenEmail) {
    res.json({message: "Email has already been taken"})
  } else {
    user.password = await bcrypt.hash(req.body.password, 10)

    const dbUser = new User({
      firstName: user.firstName.toLowerCase(),
      lastName: user.lastName.toLowerCase(),
      passportNumber: user.passportNumber.toLowerCase(),
      email: user.email.toLowerCase(),
      password: user.password
    })

    dbUser.save()
    res.json({message: "Success"})
  }
})
app.post("/login", (req, res) => {
    
  const userLoggingIn = req.body;

  
      User.findOne({email: userLoggingIn.email.toLowerCase()})
      .then(dbUser => {
          if (!dbUser) {
              return res.json({message: "Invalid Email or Password"})
          }
          bcrypt.compare(userLoggingIn.password, dbUser.password)
          .then(isCorrect => {
              if (isCorrect) {
                  const payload = {
                      id: dbUser._id,
                      email: dbUser.email,
                      firstName:dbUser.firstName,
                      lastName:dbUser.lastName,
                      passportNumber:dbUser.passportNumber
                  }
                  jwt.sign(
                      payload, 
                      process.env.JWT_SECRET,
                      {expiresIn: 86400},
                      (err, token) => {
                          return res.json({message: "Success", token: "Bearer " + token})
                      }
                  )
              } else {
                  return res.json({message: "Invalid Email or Password"})
              }
          })

      })
  
})

function verifyJWT(req, res, next) {
  const token = req.headers["x-access-token"]?.split(' ')[1]

  if(token) {
    jwt.verify(token, process.env.PASSPORTSECRET, (err, decoded) => {
      if(err) return res.json({
        isLoggedIn: false,
        message: "Failed To Authenticate"
      })
      req.user = {};
      req.user.id = decoded.id
      req.user.email = decoded.email
      next()
    })
  } else {
    res.json({message: "Incorrect Token Given", isLoggedIn: false})
  }
}

这是登录组件(前端)的代码:

const [email, setEmail] = useState("");
     const [password, setPassword] = useState("");


     async function loginUser(event) {
         event.preventDefault();

         const form = event.target;
         const user = {
             email: form[0].value,
             password: form[1].value
         }

         const response = await fetch('/login', {
            method: 'POST',
             headers: {
                 'Content-Type': 'application/json',
            },
             body: JSON.stringify(user),
         
         }) 

         const data = await response.json();
                  
         if(data.token) {
            localStorage.setItem("token", data.token)
            alert("Login successful!")
         } else {
             alert("Invalid email or password.")
         }
}

       useEffect(() => {
           fetch("/isUserAuth", {
               headers: {
                   "x-access-token": localStorage.getItem("token")
               }
           })
           .then(res => res.json())
           .then(data => data.isLoggedIn ? navigate("/"): null)
       }, [])

最后是注册组件(前端)的代码:


async function onSubmit(event) {
        event.preventDefault();

        const response = await fetch("/register", {
            method: "POST",
            headers: {
                "Content-type": "application/json"
            },
            body: JSON.stringify({
                firstName,
                lastName,
                passportNumber,
                email,
                password,
            })
        })

        const data = await response.json()

        if (data.message === "Success") {
            alert("Registeration successful!")
            navigate('/login')
        } else {
            alert("Email already taken.")
        }
        
    }

    useEffect(() => {
        fetch("/isUserAuth", {
            headers: {
                "x-access-token": localStorage.getItem("token")
            }
        })
        .then(res => res.json())
        .then(data => data.isLoggedIn ? navigate("/"): null)

        
    }, [])

包含密钥的 .env 文件:

JWT_SECRET=secret123
PASSPORTSECRET=secret123

我认为错误来自 .env 文件中的密钥。但是,我不认识这个问题。谁能给个提示?

【问题讨论】:

  • jwt.sign 的回调中,您是否尝试检查err 变量中的内容?也许这会给你一个关于哪里出了问题的提示。
  • 我不需要 server.js 中的 .env 文件,因此没有定义 JWT_SECRET。无论如何感谢您的帮助! @MichalTrojanowski

标签: reactjs authentication jwt bearer-token


【解决方案1】:

在您的 server.js 文件中,token 应该由 jwt.sign 方法生成,如下所示:

const token = jwt.sign(
  payload,
  process.env.JWT_SECRET,
  {
    expiresIn: 86400,
  }
);
// save user token
user.token = token;

// user
res.status(200).json(user);

【讨论】:

  • jwt.sign 也接受回调,因此不必将其分配给变量。
  • @nos nart 感谢您的回复。但是,我的错误是我的 server.js 中不需要 .env 文件
  • @MichalTrojanowski 是的,没必要。
猜你喜欢
  • 2020-08-23
  • 1970-01-01
  • 2017-02-24
  • 1970-01-01
  • 2014-04-09
  • 1970-01-01
  • 2015-12-25
  • 2011-03-18
  • 1970-01-01
相关资源
最近更新 更多