VueJS和Express Pass CSRF令牌发布

时间:2019-01-06 20:43:54

标签: express vue.js axios

我在后端使用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 个答案:

答案 0 :(得分:0)

我必须正确地将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();
});
...