是否可以在next.js中将客户端(浏览器)cookie发送到服务器端,以便它可以在服务器端使用?

ztyzrc3y  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(110)

我使用Next.js作为前端,Laravel(sanctum)作为后端。
由于我使用Sanctum进行SPA身份验证,因此它在浏览器中存储cookie。这些cookie对用户进行身份验证并将请求发送到受保护的API端点。我使用breeze-next初学者工具包;它提供了一个useAuth钩子来执行所有身份验证任务并获取经过身份验证的用户
它通过调用受保护的端点api/user来获取用户
src/hooks/auth.js

const { data:user, error, mutate } = useSWR("/api/user", () =>
    axios
      .get("/api/user")
      .then((res) => res.data)
      .catch((error) => {
        if (error.response.status !== 409) throw error;
        router.push("/verify-email");
      })
      .finally(function () {
        setUserLoading(false)
      })
  );

字符串
并且稍微修改AXIOS以将所存储的cookie与访问受保护路由的请求一起发送。
src/lib/axios.js

import Axios from "axios";

const axios = Axios.create({
  baseURL: process.env.NEXT_PUBLIC_BACKEND_URL,
  headers: {
    "X-Requested-With": "XMLHttpRequest",
  },
  withCredentials: true,
});

export default axios;


所以useAuth只在客户端工作。在服务器端使用它会产生像这样的错误Error: (0 , _hooks_auth__WEBPACK_IMPORTED_MODULE_1__.useAuth) is not a function
现在我想解决的问题是在前端阻止受保护的路由。在纯HTML/CSS的laravel中,访问它将重定向到登录页面。我想直接从服务器端在next.js中做类似的事情,不是在客户端。我考虑过使用useEffect,检查用户是否经过身份验证,然后使用window.location.replace。但这需要一些时间。时间来获取用户数据和决定。同时,它会显示受保护的路由。但我想阻止它并从服务器决定它。我尝试了this,但useAuth不能在服务器上使用。所以,我试图将客户端cookie发送到服务器端并使用它来调用api/user。我使用了next.js中间件。
middleware.js

import { NextResponse } from 'next/server';

export function middleware(request) {
    console.log(`=== ${request.url}`);
    // console.log(request)
    // console.log(request.headers)
    console.log(request.cookies.get('laravel_session'));
    console.log(request.cookies.get('XSRF-TOKEN'));
    console.log('=== -- ===');

    let response = NextResponse.next();
    response.cookies.set('XSRF-TOKEN', request.cookies.get('XSRF-TOKEN')?.value)
    // console.log(response);

    return response;
}

export const config = {
    // matcher: ['/admin/:path*'],
};
import dns from 'node:dns';
import { cookies } from 'next/headers';
import axios from './axios';

export const getAuthenticatedUser = () => {
    dns.setDefaultResultOrder('ipv4first');

    axios.get(`${process.env.NEXT_PUBLIC_BACKEND_URL}/api/user`)
    // fetch(`${process.env.NEXT_PUBLIC_BACKEND_URL}/api/user`, {
    //     credentials: 'include',
    //     method: 'GET',
    //     headers: {
    //         'X-Requested-With': 'XMLHttpRequest',
    //         'X-XSRF-Token': cookies().get('XSRF-TOKEN').value,
    //     },
    // })
    .then((response) => {
        console.log(response);
    });
};

的字符串
但是它不起作用。它给了401。我还检查了服务器上收到的令牌,它与浏览器中存储的令牌不匹配。
有人知道其他的选择吗?

tpgth1q7

tpgth1q71#

在Next.js中向服务器端发送客户端cookie涉及一些注意事项。当从服务器端发出请求时,您需要确保cookie随请求一起沿着发送。以下是一些故障排除和潜在解决问题的建议:
1.**验证Cookie配置:**请确保您的Cookie设置正确,尤其是与域名和路径相关的设置,客户端设置的Cookie应能被服务器访问。
1.**显式传递Cookie:**在您的服务器端函数或API路由中,将Cookie从传入请求显式传递到传出请求。修改您的getAuthenticatedUser函数接受请求对象,并使用headers属性传递Cookie:

// Import necessary modules
import axios from './axios';

export const getAuthenticatedUser = (req) => {
    // Access cookies from the incoming request
    const xsrfToken = req.cookies['XSRF-TOKEN'];

    // Make the request with the token
    axios.get(`${process.env.NEXT_PUBLIC_BACKEND_URL}/api/user`, {
        headers: {
            'X-Requested-With': 'XMLHttpRequest',
            'X-XSRF-Token': xsrfToken,
        },
    })
    .then((response) => {
        console.log(response);
    })
    .catch((error) => {
        console.error(error);
    });
};

字符串
然后,在您的API路由或服务器端函数中,调用此函数并传递请求对象:

import { getAuthenticatedUser } from 'path/to/getAuthenticatedUser';

export default async function handler(req, res) {
    // Call the function with the request object
    await getAuthenticatedUser(req);

    // Return the response
    res.status(200).json({ message: 'Success' });
}


1.**确保包含凭证:**从服务器端发出请求时,确保包含凭证。将credentials选项设置为'include'

axios.get(`${process.env.NEXT_PUBLIC_BACKEND_URL}/api/user`, {
    credentials: 'include',
    headers: {
        'X-Requested-With': 'XMLHttpRequest',
        'X-XSRF-Token': xsrfToken,
    },
})


1.**检查CORS配置:**确保您的后端配置为处理跨域请求,并包含相应的CORS头,允许凭据。
1.**检查:**使用浏览器开发工具检查客户端的cookie,并将其与服务器端接收的cookie进行比较。确保cookie与请求一起发送。

相关问题