1

我接下来使用 zeit 来制作一个带有 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;
4

2 回答 2

3

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

希望这对你有用。

于 2017-08-28T09:17:33.677 回答
1

当您刷新页面时,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}
        })
于 2017-08-28T09:01:09.910 回答