我正在使用NextJS作为客户端存储库来与我的后端API服务器(laravel)进行通信。验证通过存储在cookie中的JWT完成。当我向Cookie发送响应并设置为my-backend-server.com域时,向https://my-backend-server.com/api/login
发送身份验证请求时,所有操作均无缝进行。甚至当我从浏览器发送请求时。
当我要加载页面并从getInitialProps发送请求时出现问题,因为这是服务器端调用。我怎么能访问到my-backend-server.com
的cookie并将其放在标题中,以便正确授权NextJS的服务器端请求?
大多数答案都讲关于req.cookies
或req.headers.cookies
的内容,但这是空的,因为getInitialProps中的请求是向http://my-local-clientside-site.com
答案 0 :(得分:0)
正如您正确解释的那样,在客户端和服务器上调用Next的getInitialProps
。
如果您的Next app和Api服务是从同一域提供的,则您的Api服务可以将Cookie放在该域中,并且它将在客户端(浏览器)上运行。
每当您的下一个应用程序从服务器端访问api时,您都需要自己附加cookie。
服务器端的 getInitialProps
方法从浏览器获取上下文(第一参数)的请求(作为req
),这意味着该请求具有 cookie
如果您有自定义服务器,则可能需要在其中添加一个cookieParser,
// server.js
import cookieParser from 'cookie-parser';
import express from 'express';
import next from 'next';
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
app.prepare().then(() => {
const nextHandler = app.getRequestHandler();
const server = express();
server.use(cookieParser());
// -----------^
server.get('*', (req, res) => nextHandler(req, res));
});
此解析器将解析Cookie
标头,并将其作为对象放在req
上。
此后,您的req.cookie
应该具有cookie值(确保您看到浏览器在文档请求中发送了它),您可以在getInitialProps
中访问它,
//pages/index.js
const IndexPage = () => <div>BLA</div>
IndexPage.getInitialProps = (context) => {
if(context.req) {
// it runs on server side
axios.defaults.headers.get.Cookie = context.req.cookie;
}
};
我为您提供了一个示例,该示例定义了axios,以便将cookie放在将由客户端发出的所有请求上。
答案 1 :(得分:-3)
Felixmosh的回答是正确的一半。而不是context.req.cookie,它应该是context.req.headers.cookie。
const IndexPage = () => <div>BLA</div>
IndexPage.getInitialProps = (context) => {
if(context.req) {
// it runs on server side
axios.defaults.headers.get.Cookie = context.req.headers.cookie;
//make api call with axios - it would have correct cookies to authenticate your api call
}
};