在服务器端渲染(节点/ Express)中反应Cookie

时间:2019-04-15 13:05:43

标签: javascript node.js reactjs express cookies

我有一个React服务器端渲染的Web应用程序。

当用户请求“ myapp.com/data”时,我将设置一个Node Express通配符路由来捕获该请求。在该路由处理程序内,我为服务器创建Redux存储,然后渲染

app.get("/*", (req, res) => {
const content = renderToString(
    <Provider store={store}>
      <StaticRouter location={req.path} context={{}}>
        <Routes />
      </StaticRouter>
    </Provider>
  );
// send a bunch of HTML to client with {content} inside the React root div
}

很显然,我有客户端代码来水合内容。我为客户端创建了其他商店,但我认为这与问题无关。

const store = createStore(
  reducers,
  {},
  composeEnhancers(applyMiddleware(thunk))
);

const jsx = (
  <Provider store={store}>
    <BrowserRouter>
      <Routes />
    </BrowserRouter>
  </Provider>
);

ReactDOM.hydrate(jsx, document.querySelector("#react-root"));

我设置了一项服务,以使用“通用cookie”来完成cookie的所有获取和设置。

import Cookie from "universal-cookie";
...
...
login(args) {
    const cookie = new Cookie();
    return new Promise((resolve, reject) => {
      fetch(`${apiURLs.login}`, {
        method: "post",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(args)
      })
        .then(response => {
          if (response.status !== 200)
            throw { status: response.status, message: response.message };
          return response.json();
        })
        .then(json => {
          cookie.set("authToken", json.authToken);
          resolve(json);
        })
        .catch(error => {
          reject(error);
        });
    });
  }

一切正常。

在我的客户端代码中,我创建了一个组件。

import Cookie from "universal-cookie";
...
...
const PrivateRoute = ({ component: Component, ...rest }) => {
  const cookie = new Cookie();
  const authToken = cookie.get("authToken");
  console.log("Auth Token inside <PrivateRoute /> = ");
  console.log(authToken);
  return (
    <Route
      {...rest}
      render={props => {
        return AuthService.checkToken("authToken").then(response => {
          return response.success;
        }) === true ? (
          <Component {...props} />
        ) : (
          <Redirect
            to={{
              pathname: "/login",
              state: {
                referrer: props.location
              }
            }}
          />
        );
      }}
    />
  );
};

问题(tl; dr):

const authToken = cookie.get("authToken");
console.log("Auth Token inside <PrivateRoute /> = ");
console.log(authToken);

在我的PrivateRoute组件中,身份验证令牌在服务器生成的代码上记录“未定义” ,并在客户端返回正确的值。

1 个答案:

答案 0 :(得分:1)

universal-cookie lib如何获取Cookie? 从文档中,您需要将cookie标头传递给构造函数。

// Server Example
import Cookies from 'universal-cookie';

const cookies = new Cookies(req.headers.cookie);

console.log(cookies.get('myCat')); // Pacman or undefined if not set yet

我建议您重构此代码,以便您的组件不知道数据(cookie)的来源。

一个常见的选择是在创建商店时将其放置在redux商店中(也可以在初始商店中)。

使用这种方法,您将需要在客户端(在这种情况下初始化商店时,从document.cookie中读取cookie)和服务器端(在初始化商店时,在这种情况下,从cookie中读取)读取cookie请求对象)。