这里是它的 GitHub:https://github.com/cornflourblue/node-mongo-signup-verification-api
所以我们有这两条路线:
router.post('/authenticate', authenticateSchema, authenticate);
router.post('/refresh-token', refreshToken);
然后这有两个控制器:
function authenticate(req, res, next) {
const { email, password } = req.body;
const ipAddress = req.ip;
accountService.authenticate({ email, password, ipAddress })
.then(({ refreshToken, ...account }) => {
setTokenCookie(res, refreshToken);
res.json(account);
})
.catch(next);
}
function refreshToken(req, res, next) {
const token = req.cookies.refreshToken;
const ipAddress = req.ip;
accountService.refreshToken({ token, ipAddress })
.then(({ refreshToken, ...account }) => {
setTokenCookie(res, refreshToken);
res.json(account);
})
.catch(next);
}
这是 setTokenCookie
函数:
function setTokenCookie(res, token) {
// create cookie with refresh token that expires in 7 days
const cookieOptions = {
httpOnly: true,
expires: new Date(Date.now() + 7*24*60*60*1000)
};
res.cookie('refreshToken', token, cookieOptions);
}
在 accountService
中,我有我们上面看到的这些函数:
async function authenticate({ email, password, ipAddress }) {
const account = await db.Account.findOne({ email });
if (!account || !account.isVerified || !bcrypt.compareSync(password, account.passwordHash)) {
throw 'Email or password is incorrect';
}
// authentication successful so generate jwt and refresh tokens
const jwtToken = generateJwtToken(account);
const refreshToken = generateRefreshToken(account, ipAddress);
// save refresh token
await refreshToken.save();
// return basic details and tokens
return {
...basicDetails(account),
jwtToken,
refreshToken: refreshToken.token
};
}
async function refreshToken({ token, ipAddress }) {
const refreshToken = await getRefreshToken(token);
const { account } = refreshToken;
// replace old refresh token with a new one and save
const newRefreshToken = generateRefreshToken(account, ipAddress);
refreshToken.revoked = Date.now();
refreshToken.revokedByIp = ipAddress;
refreshToken.replacedByToken = newRefreshToken.token;
await refreshToken.save();
await newRefreshToken.save();
// generate new jwt
const jwtToken = generateJwtToken(account);
// return basic details and tokens
return {
...basicDetails(account),
jwtToken,
refreshToken: newRefreshToken.token
};
}
如您所见,当我点击 authenticate
一个新的 jwtToken
和 refreshToken
创建并使用 setTokenCookie(res, refreshToken);
函数时,我们将 refreshToken
存储在一个 {{1} } cookie,但是没有 httpOnly
保存在 cookie 中!!!并且 jwtToken
被保存到数据库中,以便在我点击 refreshToken
路线时获取用户帐户...
问题是我们需要在哪里以及如何保存 jwtToken?
如果我们需要通过授权标头发送 refreshToken
,如果我们不在任何地方存储它,我们如何访问它?
每次需要对用户进行身份验证时,是否都需要点击 jwtToken
路由并获取新的 refreshToken
?