我正在构建一个Web应用程序,只有注册用户可以访问。我使用JWT创建安全令牌。当用户进行新查询时(例如直接在地址栏中键入内容或打开浏览器),由于请求未与Authorization标头一起发送,因此我创建了一个脚本以重定向到临时页面,该脚本将从本地提取保存的令牌存储(如果存在),然后使用授权标头再次发送原始请求。
但是,当我这样做时,请求工作(将get请求发送到原始页面,包含正确的授权标头),但是由于window.location没有更新,因此页面未在客户端上呈现(尽管它在服务器端)。当我添加“ window.location.replace()”行对其进行更新时,它将发送一个新的Get请求,但这次没有授权标头。
设计如下:当将get请求发送到任何安全页面时,它将检查req是否具有授权标头。如果不是,它将重定向到一个特殊页面,该页面仅呈现客户端JavaScript以检查本地令牌是否存储在本地。该脚本将发布到同一页面,并且如果找到令牌,则它将在发送授权标头时返回到原始请求。否则,它将呈现“ 403”错误页面。
如前所述,该程序在将授权标头发送回原始请求时,运行良好。问题出在客户端获取渲染。
我需要更新客户端窗口位置以获得渲染结果。我尝试了window.location(不发送任何标头)的替代方法,例如发出XMLHttp请求或fetch请求(我已经实现了chrome 75,并带有fetch api),还有AJAX。但是它们都不会更新位置:它们实际上可以很好地发送标头,但是一旦结束,我仍然需要触发window.location.replace()。
这是服务器端代码:
// Post method
app.post('/redirect', (req, res) => {
// Client should send an authorization header and it shouldn't be null
// localStorage returns null if nothing found
if(
req.headers['authorization'] !== undefined &&
req.headers['authorization'] !== null
) {
// Another server-side method I tried
//res.location(req.session.last);
//res.sendStatus(302).end();
res.redirect(req.session.last);
} else {
res.redirect('/' + req.session.lang + '/error/403');
}
});
// Get method
app.get('/redirect', (req, res) => {
if(
req.session.last !== undefined &&
typeof req.session.last === 'string'
) {
res.render('loader', {
scripts: frontScripts
});
} else {
res.redirect('/' + req.session.lang + '/error/404');
}
});
我在其中使用req.session来存储原始请求信息。
这是客户端代码:
const access = () => {
const token = localStorage.getItem('anov_auth_token');
const fetchInit = {
method: 'POST',
headers: {
'authorization': token
},
mode: 'cors',
redirect: 'follow'
};
const fetchReq = new Request('http://localhost:8080/redirect');
fetch(fetchReq, fetchInit);
// window.location.replace('http://localhost:8080/' + dest);
// this line I don't want since it makes a new request
// dest was a variable I sent from back to retrieve original query
};
window.onload = () => {
access();
};
我在原始查询中创建了console.log(),它记录了正确的令牌:
undefined
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7fSwiaWF0IjoxNTU4MTg2NDMwfQ.dq0M8fY2Azk_7KBnOpki40tj1y2W4QtLoPNrSj8EsH8
,其中未定义引用第一个请求(不包含标题)。现在,我希望我的客户端呈现原始查询。
感谢您的帮助!