如何使用客户端发送的授权标头执行重定向

时间:2019-05-18 13:53:03

标签: javascript node.js express jwt

我正在构建一个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

,其中未定义引用第一个请求(不包含标题)。现在,我希望我的客户端呈现原始查询。

感谢您的帮助!

0 个答案:

没有答案