javascript - 通过 express 处理 jwt 令牌返回错误“const token = req.cookies.auth; [0] ^ [0] [0] ReferenceError: req is not defined”
问题描述
我正在尝试完成 jwt 登录我正在尝试在登录中创建 jwt 令牌。然后我正在尝试在我的用户问题路由中使用它。
我正在使用反应前端。
这是正确的方法吗?
我目前收到错误
const token = req.cookies.auth;
[0] ^
[0]
[0] ReferenceError: req is not defined
下面是我的路由登录代码,一旦我的 sql 服务器返回电子邮件和密码的值存在,它就会分配令牌。用户问题尝试使用此 jwt。我还包括了如何在函数中验证令牌
验证用户
app.get("/user-questions", verifyToken, function(req, res) {
app.use(function(req, res, next) {
// decode token
if (token) {
jwt.verify(token, "secret", function(err, token_data) {
if (err) {
console.info("token did not work");
return res.status(403).send("Error");
} else {
req.user_data = token_data;
sql.connect(config, function(err) {
if (err) console.log(err);
// create Request object
var request = new sql.Request();
// query to the database and get the records
request.execute("dbo.ViewQuestions", function(err, recordset) {
if (err) console.log(err);
// send records as a response
res.json(recordset);
next();
});
});
}
});
} else {
console.info("no token");
console.log("no token");
return res.status(403).send("No token");
}
});
});
登录路径
app.post("/login", async (req, response) => {
try {
await sql.connect(config);
var request = new sql.Request();
var Email = req.body.email;
var Password = req.body.password;
console.log({ Email, Password });
request.input("Email", sql.VarChar, Email);
request.input("Password", sql.VarChar, Password);
var queryString =
"SELECT * FROM TestLogin WHERE email = @Email AND password = @Password";
//"SELECT * FROM RegisteredUsers WHERE email = @Email AND Password = HASHBYTES('SHA2_512', @Password + 'skrrt')";
const result = await request.query(queryString);
if (result.recordsets[0].length > 0) {
console.info("/login: login successful..");
console.log(req.body);
token = jwt.sign(
{ Email },
"secretkey",
{ expiresIn: "30s" },
(err, token) => {
res.json({
token
});
res.cookie("auth", token);
res.send("ok");
}
);
} else {
console.info("/login: bad creds");
response.status(400).send("Incorrect email and/or Password!");
}
} catch (err) {
console.log("Err: ", err);
response.status(500).send("Check api console.log for the error");
}
});
验证用户
// Verify Token
function verifyToken(req, res, next) {
// Get auth header value
const bearerHeader = req.headers["authorization"];
// Check if bearer is undefined
if (typeof bearerHeader !== "undefined") {
// Split at the space
const bearer = bearerHeader.split(" ");
// Get token from array
const bearerToken = bearer[1];
// Set the token
req.token = bearerToken;
// Next middleware
next();
} else {
// Forbidden
res.sendStatus(403);
}
}
请告知这在理论上是否可行。如果没有,请告知如何解决。
编辑 :
该错误已得到解决,但现在我的 jwt 令牌无法正常工作。当登录并手动路由到用户问题时,它不会加载组件,并且在控制台中显示 403 不可用(这是在 jwt 令牌不起作用时在代码中设置的)。
更新:
我将如何包括
['authorization'] = 'Bearer ' + token;
进入
handleSubmit(e) {
e.preventDefault();
if (this.state.email.length < 8 || this.state.password.length < 8) {
alert(`please enter the form correctly `);
} else {
const data = { email: this.state.email, password: this.state.password };
fetch("/login", {
method: "POST", // or 'PUT'
headers: {
Accept: "application/json, text/plain, */*",
"Content-Type": "application/json",
},
body: JSON.stringify(data)
})
// .then(response => response.json())
.then(data => {
console.log("Success:", data);
})
.catch(error => {
console.error("Error:", error);
});
}
}
解决方案
您的代码有几个错误:
- 在您的
/login
路线中:- 您正在尝试在发送响应后设置“auth”cookie
- 您尝试发送响应两次,一次通过
res.json
,一次通过res.send
- 您正在分配一个
token
不再存在的变量 (token = jwt.sign(...)
)
- 在你的
verifyToken
方法中:- 此方法仅验证请求是否设置了令牌,而不是验证或解码它。我会考虑将您的
jwt.verify()
电话转移到此方法。
- 此方法仅验证请求是否设置了令牌,而不是验证或解码它。我会考虑将您的
- 在您的
/user-questions
路线中:- 当这两个都打算在根级别调用时,您正在调用
app.use
inside 。app.get
删除你的app.use
电话。 - 您需要
token
从请求中获取,例如。const { token } = req;
- 您正在通过 发送回复
res.json()
,但之后您仍在致电next()
。来自Express 文档:如果当前中间件函数没有结束请求-响应周期,它必须调用 next() 将控制权传递给下一个中间件函数。
- 当这两个都打算在根级别调用时,您正在调用
这就是我将如何进行这些更改:
/login
路线:
app.post("/login", async (req, response) => {
try {
await sql.connect(config);
var request = new sql.Request();
var Email = req.body.email;
var Password = req.body.password;
console.log({ Email, Password });
request.input("Email", sql.VarChar, Email);
request.input("Password", sql.VarChar, Password);
var queryString =
"SELECT * FROM TestLogin WHERE email = @Email AND password = @Password";
//"SELECT * FROM RegisteredUsers WHERE email = @Email AND Password = HASHBYTES('SHA2_512', @Password + 'skrrt')";
const result = await request.query(queryString);
if (result.recordsets[0].length > 0) {
console.info("/login: login successful..");
console.log(req.body);
jwt.sign(
{ Email },
"secretkey",
{ expiresIn: "30s" },
(err, token) => res.cookie('auth', token).json({ token })
);
} else {
console.info("/login: bad creds");
response.status(400).send("Incorrect email and/or Password!");
}
} catch (err) {
console.log("Err: ", err);
response.status(500).send("Check api console.log for the error");
}
});
verifyToken
方法:
// Verify Token
function verifyToken(req, res, next) {
// Get auth header value
const bearerHeader = req.headers["authorization"];
// Check if bearer is undefined
if (typeof bearerHeader !== "undefined") {
// Split at the space
const bearer = bearerHeader.split(" ");
// Get token from array
const bearerToken = bearer[1];
// verify the token and store it
jwt.verify(bearerToken, "secret", function(err, decodedToken) {
if (err) {
console.info("token did not work");
return res.status(403).send("Error");
}
// Set the token
req.token = bearerToken;
req.decodedToken = decodedToken;
next();
});
} else {
// Forbidden
res.sendStatus(403);
}
}
/user-questions
路线:
app.get("/user-questions", verifyToken, function(req, res) {
// if a request has made it to this point, then we know they have a valid token
// and that token is available through either req.token (encoded)
// or req.decodedToken
sql.connect(config, function(err) {
if (err) console.log(err);
// create Request object
var request = new sql.Request();
// query to the database and get the records
request.execute("dbo.ViewQuestions", function(err, recordset) {
if (err) console.log(err);
// send records as a response
res.json(recordset);
});
});
});
推荐阅读
- kubernetes - Ingress serviceName 更新后如何应用转换器插件?
- html - 可以压缩单元格中的 div 的网格或表格
- regex - 如何正确解析带有 regexextract() 的带有 arrayformula() 的字符串到它们 sum() 它们?
- haskell - Bifunctor 实例定义上的类型签名不匹配
- tfs - 使用 TF VC 命令替换“Team Foundation PowerTools”TFPT GETCS 命令
- django - django 查询模型 A 并从相关模型 B 中排除一些项目
- c# - 如何从 Python 调用 .NET 的 ServiceBase.OnCustomCommand 方法?
- jackson - 压扁杰克逊
- reactjs - React 虚拟化可编辑行
- python - 正则表达式:如果字符串以所需序列开头,如何仅将内部子字符串与一组匹配