刷新页面时会话丢失(Next、react、同构)

Session lost when refresh the page (Next, react, isomorphism)

我正在使用 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;

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

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

您需要像下面的代码片段那样做一些事情。我正在使用 fetch 而不是 request

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

@PacoRampus as @neerajdngl said 刷新页面时,您的 cookie 被传递到 express 服务器,而不是在浏览器中。因此,您将被重定向到登录页面。

你可以这样做:

    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)
        });

希望这对你有用。