VueJS 和 express 传递 csrf 令牌发布
Posted
技术标签:
【中文标题】VueJS 和 express 传递 csrf 令牌发布【英文标题】:VueJS and express pass csrf token to post 【发布时间】:2019-06-01 14:38:16 【问题描述】:我在后端使用 VueJS (cli 3) & axios,以及 NodeJS - ExpressJS。我正在尝试使用 CSRF 令牌保护我的帖子用户编辑。
Vue 视图(编辑用户 - 关注 mySubmitEd):
<template>
<div class="one-user">
<h1>this user</h1>
<h2>name - surname - perm </h2>
<h2>Edit</h2>
<input type="text" v-model="name">
<input type="text" v-model="surname">
<input type="text" v-model="perm">
<button @click="mySubmitEd">Edit</button>
<button @click="mySubmit">Delete</button>
</div>
</template>
<script>
import axios from 'axios'
import io from 'socket.io-client'
export default
name: 'one-user',
data ()
return
name: '',
surname: '',
perm: '',
csrf: '',
id: this.$route.params.id,
socket: io('localhost:7000')
,
mounted ()
axios.get('http://localhost:7000/api/get-user/' + this.id)
.then(res =>
const data = res.data.user
this.name = data.name
this.surname = data.last_name
this.perm = data.permalink
this.csrf = res.data.csrfToken
axios.defaults.headers.common['X-CSRF-TOKEN'] = this.csrf
)
.catch(error => console.log(error))
,
methods:
mySubmit ()
const formData =
_id: this.id
axios.post('http://localhost:7000/api/delete-user', formData)
.then(this.$router.push( name: 'get-user' ))
.catch(error => console.log(error))
,
mySubmitEd ()
const formData =
_id: this.id,
name: this.name,
last_name: this.surname,
permalink: this.perm,
_csrf: this.csrf
console.log(formData._csrf)
axios.post('http://localhost:7000/api/update-user', formData)
.catch(error => console.log(error))
</script>
server.js 文件:
...
const cookieParser = require('cookie-parser');
const csurf = require('csurf');
...
app.use(cookieParser());
const csrfProtection = csurf( cookie: true );
app.use(csrfProtection);
...
获取用户的后端控制器:
controller.getOneUser = function(req, res)
User.findOne( _id: req.params.userId ).exec(function(err, user)
res.json(user, csrfToken: req.csrfToken());
);
;
后台更新帖:
controller.updateUser = function(req, res)
User.findById(req.body._id, function(err, user)
user.set(
name: req.body.name,
last_name: req.body.last_name,
permalink: req.body.permalink,
price: req.body.price
);
user.save();
res.send(user);
);
;
我在 NodeJS-exress 控制台中的错误:
ForbiddenError: invalid csrf token
我在浏览器中的错误:
POST http://localhost:7000/api/update-user 403 (Forbidden)
我不知道发生了什么,因为我在网络选项卡(chrome)中看到 csrf 令牌在标题和我发送的内容(例如)中是相同的:
X-CSRF-TOKEN: PddyOZrf-AdHppP3lMuWA2n7AuD8QWFG3ta0
_csrf: "PddyOZrf-AdHppP3lMuWA2n7AuD8QWFG3ta0"
我不知道我在这里想念什么。我找不到问题出在哪里。
如果您想了解更多信息,请让我帮助您。
【问题讨论】:
【参考方案1】:我必须正确传递 cookie 的标题,所以我做了 2 处更正:
Vue 视图中的第一个:
我通过了凭据:
axios.create(withCredentials: true).get(...)
和
axios.create(withCredentials: true).post(...)
其次,在路由之前的 server.js 文件中,我放了这个:
...
const corsOptions =
origin: 'http://localhost:8080',
credentials: true,
app.use(cors(corsOptions));
app.use(bodyParser.json());
app.use(cookieParser());
const csrfProtection = csurf( cookie: true );
app.use(csrfProtection);
app.use(function (req, res, next)
res.cookie('XSRF-TOKEN', req.csrfToken());
res.locals._csrf = req.csrfToken();
next();
);
...
【讨论】:
以上是关于VueJS 和 express 传递 csrf 令牌发布的主要内容,如果未能解决你的问题,请参考以下文章
如何在 VueJS 文件中添加 Laravel CSRF 令牌? [复制]
VueJs 前端的无效 CSRF 令牌错误(symfony 5)
将它们分开时将 Django 的 csrf_token 放入 Vuejs
CSRF 令牌不匹配错误,Laravel 5.3/VueJS2