我有一个Next JS前端和Laravel 9作为后端。创建了API并在邮递员上进行了测试。所有API运行良好,没有任何问题。
问题
因此,我创建了一个带有表单的Nextjs文件,并使用Axios发布数据。我得到了Error: Request failed with status code 419
。
已尝试
StackOverflow上有多个类似问题的答案。我照着答案做了,但没有任何问题。
-
更改VerifyCsrfToken.php代码以禁用csrf保护。(i想要保留csrf(
-
尝试使用Axios中的headers选项添加csrf cookie。(Axios POST到Laravel API导致419个错误(
-
使用(PHP手工密钥:generate(生成密钥
-
添加了会话域
-
在web中间件中添加了路由
Route::group(['middleware' => ['api']], function () {
// our routes
});
什么在起作用
- 允许VerifyCsrfToken.php中的所有域正常工作
我想获得csrf代币
`const csrf=((=>axios.get('/sancum/csrf-cookie'('
我得到csrf令牌/csrf-cookie的空值。并且没有发现对该请求的已接受应答失败,状态代码为419。
有人知道我做错了什么吗?
尝试将中间件从web
更改为api
。
Route::group(['middleware' => ['api']], function () {
// our routes
});
如果您的前端没有csrf令牌,并且希望禁用对该特定路由的检查,则需要将该路由添加到App\Http\Middleware\VerifyCsrfToken.php中的$except数组中class:
<?php namespace AppHttpMiddleware;
use IlluminateFoundationHttpMiddlewareVerifyCsrfToken as BaseVerifier;
class VerifyCsrfToken extends BaseVerifier
{
protected $except = [
'your route here',
];
}
我不知道Nextjs,但基本上你可以把Laravel CSRF令牌放在HTML文档的元标签上,比如这个
<meta name="csrf-token" content="{{ csrf_token() }}" />
然后你可以使用像这样的简单javascript来访问它
var csrf = document.querySelector('meta[name="csrf-token"]').content;
根据laravel:的文档
在Laravel中进行这3项更改
- 更新cors策略(config/cors.php(
来源:'supports_credentials' => false,
收件人:'supports_credentials' => true,
- 在(resources/js/bootstrap.js(中添加行
axios.defaults.withCredentials = true;
- 在laravel的.env文件中添加后端和前端url
APP_URL=http://localhost:8000
FRONTEND_URL=http://localhost:3000
现在在NEXT JS应用程序中执行以下操作
在根目录下添加.env.local文件并添加以下代码。
NEXT_PUBLIC_BACKEND_URL=http://localhost:8000'
使用
npm i axios
安装axios在使用AXIOS发布数据之前,使用AXIOS导入CSRF令牌,然后使用AXIOS张贴表单数据。
这是发送或获取数据的示例代码
import React, { useEffect, useState } from 'react';
import axios from 'axios';
//optional toastify library
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
export default function index({data}) {
//console.log(data);
//setting the state (getting form data into veriable)
const [title, setTitle] = useState('')
const [desc, setDesc] = useState('')
// preventing default and showing the data in console
const formSubmit = async (e) => {
e.preventDefault();
console.log(title ,desc);
// setting csrf token
await axios.get('http://localhost:8000/sanctum/csrf-cookie').then(getcsrvf => {
//console.log(getcsrvf);
// posting the data using axios / creating the data.
axios.post('http://localhost:8000/api/post', {title,desc})
.then(function (response) {
//alert(response.data.message);
toast(response.data.message);
console.log(response);
})
.catch(function (error) {
//console.log(error);
});
});
}
return (
// bootstrap installed
<div className=' pt-5'>
<div className='container'>
//basic jsx form
<form onSubmit={formSubmit}>
<div className='mb-2'>
{/* onChange={(e)=>{setName(e.target.value)}} */}
<input type="text" onChange={(e) => {setTitle(e.target.value)}} value={title} className="form-control mb-2 py-2" placeholder="title" name="title" id='title' />
</div>
<div className='mb-2'>
<input type="text" onChange={(e) => {setDesc(e.target.value)}} value={desc} className="form-control mb-2 py-2" placeholder="desc" name="desc" id='desc' />
</div>
<div className='mb-2'>
<button className='btn btn-primary'>Submit</button>
</div>
</form>
</div>
<hr/>
//looping the post data
{data.post.map((post, i)=>{
return (
<div className='container' key={i}>
<h3>{post.title}</h3>
<p>{post.desc}</p>
<hr/>
</div>
)
})}
<ToastContainer position="top-center" pauseOnHover="false"/>
</div>
)
}
// Getting the records // reading the data
export async function getServerSideProps() {
const res = await fetch("http://localhost:8000/api/post")
const data = await res.json()
return{
props: {
data
}
}
}
注意:请将http://localhost:8000
更改为您的laravle url,将http://localhost:3000
更改为您前端url。
上述解决方案对我有效。