【问题标题】:How to access cookie in server-side data fetch for isomorphic React app如何在同构 React 应用程序的服务器端数据获取中访问 c​​ookie
【发布时间】:2019-01-30 09:17:42
【问题描述】:

我正在构建一个同构/通用的 React + Redux + Express 应用程序。我的服务器端数据获取非常标准:我查看哪些路由与 URL 匹配,调用所有返回承诺的相关数据获取方法,然后等待它们解析并呈现 HTML。

我的挑战:某些 API 调用需要身份验证。登录的用户有一个 cookie,当然会随每个请求一起发送。但是,当我在服务器端进行数据获取以填充存储以进行初始渲染时,我的 API 调用无法使用 cookie。我该如何做到这一点?

// server-entry.jsx
app.get('*', (req, res) => {
  const store = createStore(
    combineReducers({
      // lots of reducers
    }),
    {},
    applyMiddleware(thunk),
  );
  /*
    The contents of getDataFetchers isn't important. All you need
    to know is it returns an array of data-fetching promises like so:

    dispatch(thunkAction());
  */
  const fetchers = getDataFetchers(req.url, store);

  Promise.all(fetchers).then(() => {
    // render the tree
  });
});

// one of my thunk actions hits an API endpoint looking like this:
app.get('/api', (req, res) => {
  // this is simplified, but you get the idea:
  // we need access to the cookie to authenticate
  // but when this call is made server-side, req.session.user doesn't exist
  if (!req.session.user) res.status(403);
  else res.json({ data: 'here' });
});

我想我可以从 app.get 中的 req 获取 cookie,并将其作为参数一直传递到实际数据获取(使用 axios 完成),其中将使用 @987654325 指定@标头。但这感觉很恶心。

【问题讨论】:

    标签: javascript reactjs express redux isomorphic-javascript


    【解决方案1】:

    您的建议是正确的,如果您希望服务器端 HTTP 请求包含原始请求的 cookie,则需要以允许其访问的方式构建 HTTP 客户端(在您的情况下为 axios)实例化时或发出每个请求之前的标头。

    Here is a link to how Apollo does it.

    import { ApolloProvider } from 'react-apollo';
    import { ApolloClient } from 'apollo-client';
    import { createHttpLink } from 'apollo-link-http';
    import Express from 'express';
    import { StaticRouter } from 'react-router';
    import { InMemoryCache } from "apollo-cache-inmemory";
    
    import Layout from './routes/Layout';
    
    // Note you don't have to use any particular http server, but
    // we're using Express in this example
    const app = new Express();
    app.use((req, res) => {
    
      const client = new ApolloClient({
        ssrMode: true,
        // Remember that this is the interface the SSR server will use to connect to the
        // API server, so we need to ensure it isn't firewalled, etc
        link: createHttpLink({
          uri: 'http://localhost:3010',
          credentials: 'same-origin',
          headers: {
            cookie: req.header('Cookie'),
          },
        }),
        cache: new InMemoryCache(),
      });
    
      const context = {};
    
      // The client-side App will instead use <BrowserRouter>
      const App = (
        <ApolloProvider client={client}>
          <StaticRouter location={req.url} context={context}>
            <Layout />
          </StaticRouter>
        </ApolloProvider>
      );
    
      // rendering code (see below)
    });
    

    如您所见,ApolloClient 已创建并在实例化时传递初始请求的 cookie。

    【讨论】:

      猜你喜欢
      • 2013-01-27
      • 2022-08-20
      • 2020-05-10
      • 1970-01-01
      • 1970-01-01
      • 2022-10-15
      • 2012-06-13
      • 2010-09-11
      • 1970-01-01
      相关资源
      最近更新 更多