前端如何在Vue中安全使用Nonce随机数防止CSRF攻击?

Dev · 瑞瑞 阅读 25

我在做登录功能时,后端要求每个请求带上一个Nonce随机数来防CSRF,但我试了几次都失败了。每次页面刷新Nonce就变了,但axios拦截器里拿不到最新的值,导致请求被拒绝。

我现在的做法是在组件里用created钩子请求Nonce并存到data里,但其他组件发请求时根本拿不到这个值。是不是应该用Vuex?还是有更简单的办法?

<template>
  <button @click="submit">提交</button>
</template>

<script>
export default {
  data() {
    return { nonce: '' }
  },
  created() {
    this.nonce = fetch('/api/nonce').then(r => r.text())
  },
  methods: {
    async submit() {
      await this.$http.post('/login', {}, { headers: { 'X-Nonce': this.nonce } })
    }
  }
}
</script>
我来解答 赞 7 收藏
二维码
手机扫码查看
1 条解答
迷人的宏娟
你遇到的问题我太熟悉了,当初踩过同样的坑。问题出在你的 created 钩子里,fetch 返回的是一个 Promise,而不是直接的 nonce 值。

建议你用 Vuex 来管理这个全局状态确实是个好主意,但如果你不想引入 Vuex 的复杂性,可以用 Vue 的 provide/inject 功能,或者更简单地用一个事件总线来同步 nonce。

下面是改进后的代码示例:

export default {
data() {
return { nonce: '' }
},
async created() {
try {
const response = await fetch('/api/nonce')
this.nonce = await response.text()
} catch (error) {
console.error('获取 nonce 失败', error)
}
},
methods: {
async submit() {
if (!this.nonce) {
alert('Nonce未初始化,请刷新页面')
return
}
await this.$http.post('/login', {}, {
headers: { 'X-Nonce': this.nonce }
})
}
}
}


记得在每个需要 nonce 的组件里都加上类似的 created 钩子来获取最新值。如果页面有多个地方都需要 nonce,考虑封装成一个 mixin 或者小工具函数。

血泪教训:别忘了处理请求失败的情况,不然用户啥也看不到只会干着急。还有就是不要把 nonce 写死,每次请求都要确保是最新的。
点赞
2026-03-26 06:01