【问题标题】:Session lost when refresh the page (Next, react, isomorphism)刷新页面时会话丢失(下一步,反应,同构)
【发布时间】:2018-02-04 06:20:26
【问题描述】:

我正在使用 zeit next 来制作一个带有 react 的同构应用程序和一个带有 express-session(在其他服务器中)的 express 来制作一个 API。

此组件应从 API 请求私有数据 (request.get('http://0.0.0.0:3100/private')) 并在用户登录时显示私有页面,如果未登录则重定向到登录。

在客户端这有效,但是当我刷新私人页面时,我被重定向到登录,因为客户端和服务器端的会话 cookie 不同。 ¿ 我该如何解决这个问题?

const Private = (props) => {
    return (
        <main>
            <h1>Private </h1>
            <Link href="/">
                <a>Home</a>
            </Link>
        </main>
    );
}

Private.getInitialProps = async ({ res }) => {
    // getInitialProps is ejecuted in server side when you refresh the page (first time) 
    // but if you navigate in client side it is ejecuted in client. Server side and client
    // have a different session for API calls. Is posible to share the session by client
    // and server side? 
    const response = await request.get('http://someDomain/private');

    let body;
    if (response.status !== 401) {
        body = await response.json();
    } else {
        if (res) {
            res.writeHead(302, { Location: '/login' })
            res.end()
        } else {
            Router.push('/login')
        }
    }

    return {}
}

export default Private;

【问题讨论】:

  • 你的 sn-p 不工作,

标签: javascript reactjs fetch isomorphic-javascript nextjs


【解决方案1】:

当您刷新页面时,cookie 将被传递到 express 服务器,而不是 api。您需要在 express 中获取 cookie,然后将 cookie 与 api 请求一起传递。

当您从客户端发出 api 请求时,cookie 将与请求一起自动传递,这将验证您的 api 调用。

您需要执行以下代码 sn-p 中的操作。我正在使用 fetch 而不是 request

getCookies = encodeURIComponent(req.cookies.token);
const sendCookie = 'token=' + getCookies;
const response = await fetch(YOUR_API_ENDPOINT, {
            credentials: 'include',
            headers: {Cookie: sendCookie}
        })

【讨论】:

    【解决方案2】:

    @PacoRampus 正如@neerajdngl 所说,在刷新页面时,您的 cookie 会被传递到快速服务器,而不是在浏览器中。因此,您将被重定向到登录页面。

    你可以这样做:

        Private.getInitialProps = async ({ req, res }) => {
            let Cookie;
            if (req) {
                Cookie = encodeURIComponent(req.cookies.your_token_name);
            } else {
                Cookie = '';
            }
    
            let yourCookie= 'token=' + Cookie;
    
           const response = await fetch('http://someDomain/private', {
                credentials: 'include',
                headers: {Cookie: yourCookie}
            }));
    
            let body;
            if (response.status !== 401) {
                body = await response.json();
            } else {
                if (res) {
                    res.writeHead(302, { Location: '/login' })
                    res.end()
                } else {
                    Router.push('/login')
                }
            }
    
            return {}
        }
    

    你的 server.js 文件应该是这样的代码:

    server.get('/yourPrivatePage', (req, res) => {
                return app.render(req, res, '/yourPrivatePage', req.query)
            });
    

    希望这对你有用。

    【讨论】:

    • 谢谢,效果很好。我将完整的标头设置为 fetch : const response = await fetch('someDomain/private', { credentials: 'include', headers: req.headers }));所以客户端和服务器的 API 头文件是相同的。
    猜你喜欢
    • 2023-03-25
    • 2014-12-31
    • 2014-07-20
    • 2020-11-20
    • 2019-05-16
    • 2014-08-16
    • 1970-01-01
    • 1970-01-01
    • 2017-03-22
    相关资源
    最近更新 更多