我面临一个问题,我的应用程序因 JWT 令牌过期错误而崩溃。我也更改了密钥,但我仍然面临同样的问题。
这是代码:
中间件:
const auth = async (req, res, next) => {
try {
const token = req.headers.authorization.split(" ")[1];
const isCustomAuth = token?.length < 500;
if (!token)
{return res.status(401).json({ message: "No token provided" });}
let decodedData;
if(token && isCustomAuth){
decodedData= verifyToken(token);
req.userId = decodedData?.id;
}
else{
decodedData = jwt.decode(token);
console.log(decodedData + "decoded token");
req.userId = decodedData?.sub;
}
next();
} catch (error) {
console.log(error);
res.status(403).json({ message: "Token is not valid" });
throw Error();
}
};
代币验证
import jwt from "jsonwebtoken";
const secret = process.env.SECRET;
export const generateToken = (data) => {
try {
return jwt.sign({ email: data.email, id: data._id }, secret , { expiresIn: "24h" });
} catch(e) {
throw new Error(e)
}
}
export const verifyToken = (token) => {
try {
return jwt.verify(token, secret);
} catch(e) {
throw new Error(e)
}
}
应用程序崩溃,提示 jwt 已过期错误。请帮忙。
问题可能是您的
catch
声明:
const auth = async (req, res, next) => {
try {
// ...
} catch (error) {
console.log(error);
res.status(403).json({ message: "Token is not valid" });
throw Error(); // <--- Remove this. Don't throw in a middleware, an error response is enough
}
};
顺便说一句,还有一次改进的机会。下面的 catch 没有执行任何操作,甚至是错误的(您将一个错误实例传递给另一个错误),因此我建议您完全删除 try-catch,或者只是在那里返回一些空值。
export const verifyToken = (token) => {
try {
return jwt.verify(token, secret);
} catch(e) {
throw new Error(e) // <---- You are catching only to re-throw another error, not to mention this is a wrong way to create an error.
}
}
这个应该是
export const verifyToken = (token) => {
return jwt.verify(token, secret);
}
或者这个,然后在中间件中处理空值
export const verifyToken = (token) => {
try {
return jwt.verify(token, secret);
} catch(e) {
return null;
}
}
我们使用jwt进行身份验证,这样用户就不需要一次又一次登录。
我们在jwt认证中做了以下事情。
现在,每当前端发出请求时,它也会在请求标头中包含令牌作为授权。
代币真的会过期吗?
现在该怎么办?
简单的答案就是从 localStorage 中删除令牌。
现在你已经得到了第一个问题的答案。
现在你必须进入第二个问题。
如何做?
为此,您必须查看您用于发出请求的库的文档。 我只是给出axios的解决方案。从这里你会得到一些想法。
axios.interceptors.response.use(
(response) => {
return response;
},
(error) => {
if (error.response && error.response.status === 401) {
// remove the token from localStorage
localStorage.removeItem('token')
window.location.href = '/login';
}
return Promise.reject(error);
}
);