前端怎么防止接口请求被重放攻击?

皇甫奕卓 阅读 31

最近在做支付相关的功能,后端要求每个请求都要防重放,但我作为前端不太清楚该怎么配合。我试过加时间戳,但好像还是能被截获重放。

现在用的是 Vue3 + Axios,下面是我目前的请求封装,是不是缺了什么关键的东西?

<script setup>
import axios from 'axios'

const sendSecureRequest = async (data) => {
  const timestamp = Date.now()
  const res = await axios.post('/api/pay', {
    ...data,
    timestamp
  })
  return res.data
}
</script>
我来解答 赞 1 收藏
二维码
手机扫码查看
1 条解答
迷人的义霞
光加时间戳肯定不行,请求被抓包后几秒内重放你就没了。正确做法是 timestamp + nonce + signature 三件套,后端校验 nonce 是否重复用过就行。

省事的话直接看代码,请求拦截器里搞定:

import axios from 'axios'
import CryptoJS from 'crypto-js'

// 生成随机字符串
const generateNonce = () => {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
const r = Math.random() * 16 | 0
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16)
})
}

// 生成签名,规则跟后端对齐就行,这里用个简单示例
const generateSignature = (timestamp, nonce, data, secret) => {
const str = ${timestamp}${nonce}${JSON.stringify(data)}${secret}
return CryptoJS.MD5(str).toString()
}

const api = axios.create({
baseURL: '/api'
})

api.interceptors.request.use(config => {
const timestamp = Date.now().toString()
const nonce = generateNonce()
const secret = 'your-secret-key' // 这个跟后端约定好,别直接写死在代码里

const data = config.data || {}
const signature = generateSignature(timestamp, nonce, data, secret)

// 放请求头里,后端从header取
config.headers['X-Timestamp'] = timestamp
config.headers['X-Nonce'] = nonce
config.headers['X-Signature'] = signature

return config
})

export default api


后端那边要用 Redis 把用过的 nonce 存起来,过期时间设成跟时间戳校验窗口一致,比如5分钟。这样同一个请求就算被抓包,5分钟内重放会被 nonce 拦截,5分钟后重放会被 timestamp 拦截。
点赞
2026-03-01 03:01