node.js 请求卡在中间件功能(身份验证)中?
node.js request stuck in middleware function (authentication)?
我正在构建一个 node.js 服务器来处理我的 iOS 应用程序中的登录和操作。我写的功能之一是 checkAuth,它是我大多数请求的中间件,用于检查用户是否经过身份验证以及是否有权执行他想执行的操作。
现在我遇到一个问题,有时但并非总是如此,中间件功能 (checkAuth) 会卡住。我在我的控制台中收到来自该功能的日志,但没有收到来自请求的日志(这应该在身份验证成功后发生)。
这是我目前写的函数。它尚未优化,因为我正在测试所有内容,但它应该做我想做的事(大多数时候它会做):
const saltRounds = process.env.JWT_ROUNDS
const secret = process.env.JWT_SECRET
const checkRefreshTime = 10 // set to 10 seconds for testing, will increase later
function checkAuth(req, res, next) {
var token = req.headers['x-access-token']
jwt.verify(token, secret, (error, decoded) => {
console.log("checking auth")
if(error) {
console.log(error)
res.json({ errorCode: 406 })
} else {
const decoded = jwt.verify(token, secret)
var checkTime = (Date.now() / 1000) - checkRefreshTime;
if (decoded.iat < checkTime) {
console.log("DEC:", decoded)
const userID = decoded.userID
const queryString = "SELECT userRefreshToken, userName, userDisplayName, userProfilePicURL, userDOB, userGender FROM users WHERE userID = ? LIMIT 1"
pool.getConnection(function(error, connection) {
if(error) {
console.log(error)
res.json({ errorCode: 500 })
}
connection.query(queryString, [userID], (error, selectRows, fields) => {
if(error) {
console.log(error)
res.json({ errorCode: 500 })
}
if(selectRows.length > 0) {
if(selectRows[0].userRefreshToken == decoded.userRefreshToken) {
var userAge = moment().diff(selectRows[0].userDOB, 'years');
const payload = {
userID: userID,
userName: selectRows[0].userName,
userDisplayName: selectRows[0].userDisplayName,
userProfilePicURL: selectRows[0].userProfilePicURL,
userRefreshToken: selectRows[0].userRefreshToken,
userAge: userAge,
userGender: selectRows[0].userGender
}
var newToken = jwt.sign(payload, secret, { expiresIn: '21d' });
console.log("new token sent ", newToken)
res.locals.authToken = newToken
console.log("moving to next")
return next()
} else {
console.log("wrong refresh token")
res.json({ errorCode: 405, authResult: false })
}
} else {
console.log("0 results found!")
res.json({ errorCode: 503, authResult: false })
}
connection.release()
})
})
} else {
console.log("moving to next 2")
return next()
}
}
})
}
这可能不是您见过的最漂亮的代码。这不是我现在的问题 - 我稍后会优化。现在我担心的是,有时功能会在第二次检查后卡住。然后我收到的最后一个输出是 "DEC: ",然后是我控制台中的解码令牌(第 16 行)。
其他有用的信息:我 运行 我的服务器在 DigitalOcean 的 Ubuntu 18.04 服务器上并永久使用 运行ning:
forever start --minUptime 1000 --spinSleepTime 1000 server.js
有人知道为什么会这样吗?
编辑:根据评论,pool
的定义
var pool = mysql.createPool({
connectionLimit: 100,
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASS,
database: process.env.DB_BASE,
ssl : {
ca : fs.readFileSync('***********'),
key : fs.readFileSync('*********'),
cert : fs.readFileSync('********'),
},
charset : 'utf8mb4',
dateStrings: true
})
我没看到 pool
在哪里定义。这可能会在服务器日志中引发错误。
在连接函数中放置控制台日志以检查它是否实际连接到 mySQL,因为这是链中的下一个函数。
我正在构建一个 node.js 服务器来处理我的 iOS 应用程序中的登录和操作。我写的功能之一是 checkAuth,它是我大多数请求的中间件,用于检查用户是否经过身份验证以及是否有权执行他想执行的操作。
现在我遇到一个问题,有时但并非总是如此,中间件功能 (checkAuth) 会卡住。我在我的控制台中收到来自该功能的日志,但没有收到来自请求的日志(这应该在身份验证成功后发生)。
这是我目前写的函数。它尚未优化,因为我正在测试所有内容,但它应该做我想做的事(大多数时候它会做):
const saltRounds = process.env.JWT_ROUNDS
const secret = process.env.JWT_SECRET
const checkRefreshTime = 10 // set to 10 seconds for testing, will increase later
function checkAuth(req, res, next) {
var token = req.headers['x-access-token']
jwt.verify(token, secret, (error, decoded) => {
console.log("checking auth")
if(error) {
console.log(error)
res.json({ errorCode: 406 })
} else {
const decoded = jwt.verify(token, secret)
var checkTime = (Date.now() / 1000) - checkRefreshTime;
if (decoded.iat < checkTime) {
console.log("DEC:", decoded)
const userID = decoded.userID
const queryString = "SELECT userRefreshToken, userName, userDisplayName, userProfilePicURL, userDOB, userGender FROM users WHERE userID = ? LIMIT 1"
pool.getConnection(function(error, connection) {
if(error) {
console.log(error)
res.json({ errorCode: 500 })
}
connection.query(queryString, [userID], (error, selectRows, fields) => {
if(error) {
console.log(error)
res.json({ errorCode: 500 })
}
if(selectRows.length > 0) {
if(selectRows[0].userRefreshToken == decoded.userRefreshToken) {
var userAge = moment().diff(selectRows[0].userDOB, 'years');
const payload = {
userID: userID,
userName: selectRows[0].userName,
userDisplayName: selectRows[0].userDisplayName,
userProfilePicURL: selectRows[0].userProfilePicURL,
userRefreshToken: selectRows[0].userRefreshToken,
userAge: userAge,
userGender: selectRows[0].userGender
}
var newToken = jwt.sign(payload, secret, { expiresIn: '21d' });
console.log("new token sent ", newToken)
res.locals.authToken = newToken
console.log("moving to next")
return next()
} else {
console.log("wrong refresh token")
res.json({ errorCode: 405, authResult: false })
}
} else {
console.log("0 results found!")
res.json({ errorCode: 503, authResult: false })
}
connection.release()
})
})
} else {
console.log("moving to next 2")
return next()
}
}
})
}
这可能不是您见过的最漂亮的代码。这不是我现在的问题 - 我稍后会优化。现在我担心的是,有时功能会在第二次检查后卡住。然后我收到的最后一个输出是 "DEC: ",然后是我控制台中的解码令牌(第 16 行)。
其他有用的信息:我 运行 我的服务器在 DigitalOcean 的 Ubuntu 18.04 服务器上并永久使用 运行ning:
forever start --minUptime 1000 --spinSleepTime 1000 server.js
有人知道为什么会这样吗?
编辑:根据评论,pool
var pool = mysql.createPool({
connectionLimit: 100,
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASS,
database: process.env.DB_BASE,
ssl : {
ca : fs.readFileSync('***********'),
key : fs.readFileSync('*********'),
cert : fs.readFileSync('********'),
},
charset : 'utf8mb4',
dateStrings: true
})
我没看到 pool
在哪里定义。这可能会在服务器日志中引发错误。
在连接函数中放置控制台日志以检查它是否实际连接到 mySQL,因为这是链中的下一个函数。