我使用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
。我还检查了服务器上收到的令牌,它与浏览器中存储的令牌不匹配。
有人知道其他的选择吗?
1条答案
按热度按时间tpgth1q71#
在Next.js中向服务器端发送客户端cookie涉及一些注意事项。当从服务器端发出请求时,您需要确保cookie随请求一起沿着发送。以下是一些故障排除和潜在解决问题的建议:
1.**验证Cookie配置:**请确保您的Cookie设置正确,尤其是与域名和路径相关的设置,客户端设置的Cookie应能被服务器访问。
1.**显式传递Cookie:**在您的服务器端函数或API路由中,将Cookie从传入请求显式传递到传出请求。修改您的
getAuthenticatedUser
函数接受请求对象,并使用headers
属性传递Cookie:字符串
然后,在您的API路由或服务器端函数中,调用此函数并传递请求对象:
型
1.**确保包含凭证:**从服务器端发出请求时,确保包含凭证。将
credentials
选项设置为'include'
:型
1.**检查CORS配置:**确保您的后端配置为处理跨域请求,并包含相应的CORS头,允许凭据。
1.**检查:**使用浏览器开发工具检查客户端的cookie,并将其与服务器端接收的cookie进行比较。确保cookie与请求一起发送。