XSRF 防御「建议收藏」

XSRF 防御「建议收藏」#XSRF防御#需求分析XSRF又名CSRF(opensnewwindow),跨站请求伪造,它是前端常见的一种攻击方式,我们先通过一张图来认识它的攻击手段。CSRF的防御手段有很多,比如验证请求的referer,但是referer也是可以伪造的,所以杜绝此类攻击的一种方式是服务器端要求每次请求都包含一个token,这个token不在前端生成,而是在我们每次访…

大家好,又见面了,我是你们的朋友全栈君。

XSRF 又名 CSRF
(opens new window)
,跨站请求伪造,它是前端常见的一种攻击方式,我们先通过一张图来认识它的攻击手段。

xsrf

CSRF 的防御手段有很多,比如验证请求的 referer,但是 referer 也是可以伪造的,所以杜绝此类攻击的一种方式是服务器端要求每次请求都包含一个 token,这个 token 不在前端生成,而是在我们每次访问站点的时候生成,并通过 set-cookie 的方式种到客户端,然后客户端发送请求的时候,从 cookie 中对应的字段读取出 token,然后添加到请求 headers 中。这样服务端就可以从请求 headers 中读取这个 token 并验证,由于这个 token 是很难伪造的,所以就能区分这个请求是否是用户正常发起的。

对于我们的 ts-axios 库,我们要自动把这几件事做了,每次发送请求的时候,从 cookie 中读取对应的 token 值,然后添加到请求 headers中。我们允许用户配置 xsrfCookieNamexsrfHeaderName,其中 xsrfCookieName 表示存储 tokencookie 名称,xsrfHeaderName 表示请求 headerstoken 对应的 header 名称。

axios.get('/more/get',{ 
     
  xsrfCookieName: 'XSRF-TOKEN', // default
  xsrfHeaderName: 'X-XSRF-TOKEN' // default
}).then(res => { 
     
  console.log(res)
})

我们提供 xsrfCookieNamexsrfHeaderName 的默认值,当然用户也可以根据自己的需求在请求中去配置 xsrfCookieNamexsrfHeaderName

先修改 AxiosRequestConfig 的类型定义。

types/index.ts

export interface AxiosRequestConfig { 
     
  // ...
  xsrfCookieName?: string
  xsrfHeaderName?: string
}

然后修改默认配置。

defaults.ts

const defaults: AxiosRequestConfig = { 
     
  // ...
  xsrfCookieName: 'XSRF-TOKEN',

  xsrfHeaderName: 'X-XSRF-TOKEN',
}

接下来我们要做三件事:

  • 首先判断如果是配置 withCredentialstrue 或者是同域请求,我们才会请求 headers 添加 xsrf 相关的字段。

  • 如果判断成功,尝试从 cookie 中读取 xsrftoken 值。

  • 如果能读到,则把它添加到请求 headersxsrf 相关字段中。

我们先来实现同域请求的判断。

helpers/url.ts

interface URLOrigin { 
     
  protocol: string
  host: string
}


export function isURLSameOrigin(requestURL: string): boolean { 
     
  const parsedOrigin = resolveURL(requestURL)
  return (
    parsedOrigin.protocol === currentOrigin.protocol && parsedOrigin.host === currentOrigin.host
  )
}

const urlParsingNode = document.createElement('a')
const currentOrigin = resolveURL(window.location.href)

function resolveURL(url: string): URLOrigin { 
     
  urlParsingNode.setAttribute('href', url)
  const { 
      protocol, host } = urlParsingNode

  return { 
     
    protocol,
    host
  }
}

同域名的判断主要利用了一个技巧,创建一个 a 标签的 DOM,然后设置 href 属性为我们传入的 url,然后可以获取该 DOM 的 protocolhost。当前页面的 url 和请求的 url 都通过这种方式获取,然后对比它们的 protocolhost 是否相同即可。

接着实现 cookie 的读取。

helpers/cookie.ts

const cookie = { 
     
  read(name: string): string | null { 
     
    const match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)'))
    return match ? decodeURIComponent(match[3]) : null
  }
}

export default cookie

cookie 的读取逻辑很简单,利用了正则表达式可以解析到 name 对应的值。

最后实现完整的逻辑。

core/xhr.ts

const { 
     
  /*...*/
  xsrfCookieName,
  xsrfHeaderName
} = config

if ((withCredentials || isURLSameOrigin(url!)) && xsrfCookieName){ 
     
  const xsrfValue = cookie.read(xsrfCookieName)
  if (xsrfValue) { 
     
    headers[xsrfHeaderName!] = xsrfValue
  }
}

const instance = axios.create({ 
     
  xsrfCookieName: 'XSRF-TOKEN-D',
  xsrfHeaderName: 'X-XSRF-TOKEN-D'
})

instance.get('/more/get').then(res => { 
     
  console.log(res)
})

examples/server.js

app.use(express.static(__dirname, { 
     
  setHeaders (res) { 
     
    res.cookie('XSRF-TOKEN-D', '1234abc')
  }
}))

在访问页面的时候,服务端通过 set-cookie 往客户端种了 keyXSRF-TOKEN,值为 1234abccookie,作为 xsrftoken 值。

然后我们在前端发送请求的时候,就能从 cookie 中读出 keyXSRF-TOKEN 的值,然后把它添加到 keyX-XSRF-TOKEN 的请求 headers 中。

至此,我们实现了 XSRF 的自动防御的能力,下节课我们来实现 ts-axios 对上传和下载请求的支持。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/144273.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 深度优先遍历和广度优先遍历[通俗易懂]

    深度优先遍历和广度优先遍历[通俗易懂]深度优先遍历和广度优先遍历什么是深度/广度优先遍历?深度优先遍历简称DFS(DepthFirstSearch),广度优先遍历简称BFS(BreadthFirstSearch),它们是遍历图当中所有顶点的两种方式。这两种遍历方式有什么不同呢?我们来举个栗子:我们来到一个游乐场,游乐场里有11个景点。我们从景点0开始,要玩遍游乐场的所有景点,可以有什么…

    2022年6月13日
    45
  • 头歌c语言实训作业题解

    头歌c语言实训作业题解头歌c语言实训作业题解顺序结构程序设计1.加法运算2.不使用第3个变量,实现两个数的对调3.用宏定义常量4.数字分离5.计算总成绩和平均成绩6.求三角形面积7.立体几何计算题8.计算两个正整数的最大公约数选择结构程序设计选择结构程序设计进阶顺序结构程序设计1.加法运算本关任务:写一个加法程序,输入整数a,b,输出他们的和。解题代码:#include<stdio.h> intmain(void) { inta,b,c;//Pleaseinputa

    2022年5月12日
    41
  • k8s(二)搭建「建议收藏」

    k8s(二)搭建「建议收藏」k8s安装 初始化环境kubernetes必要组件安装集群安装一主多从多主多从安装 初始化环境minibuke 用于快速构建单节点k8s的工具kubeadm 用于快速搭建k8s集群的工具二进制包 从官网下载每个组件的二进制包 一次去安装 对于理解k8s更有效作用nathostmaster10.0.3.11192.168.56.101node110.0.3.12192.168.56.102node210.0.3.14192.168.56.1

    2022年8月9日
    7
  • 2015年2月编程语言排行榜:JavaScript排名达到历史最高

    2015年2月编程语言排行榜:JavaScript排名达到历史最高

    2021年9月4日
    50
  • java交通信号灯毕业论文范文_信号灯设计论文,关于基于FPGA的交通信号灯控制系统设计相关参考文献资料-免费论文范文…[通俗易懂]

    java交通信号灯毕业论文范文_信号灯设计论文,关于基于FPGA的交通信号灯控制系统设计相关参考文献资料-免费论文范文…[通俗易懂]导读:本文关于信号灯设计论文范文,可以做为相关参考文献。文/胡桂戎陕西警官职业学院陕西西安710021【摘要】本文采用FPGA设计,结合了道路传感器,设计了交通信号灯全感应自适应的控制方案.通过仿真与验证结果表明实现对交通道路的畅通达到优化的效果.【关键词】FPGA;信号灯;系统现代城市交通车流量大,交通信号灯的时间控制和状态转化往往是造成交通效率高低的主要原因.因此,就需要对信号灯…

    2022年9月15日
    1
  • linux文本编辑器

    linux文本编辑器linux常见服务一.文本编辑器vivim是vi增强版vim需要安装sudoapt-get-yinstallvimvim的三种工作模式1编辑模式命令模式=&gt;编辑模式iaos按键作用i在光标当前位置插入文本a光标的下一个位置插入文本A当前行的行尾插入文本S…

    2022年6月10日
    52

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号