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 对上传和下载请求的支持。

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • javaScript模块化解析「建议收藏」

    javaScript模块化解析「建议收藏」JavaScript模块化解析什么是模块化?到底什么是模块化、模块化开发呢?事实上模块化开发最终的目的是将程序划分成一个个小的结构;这个结构中编写属于自己的逻辑代码,有自己的作用域,不会影响到其他的结构;这个结构可以将自己希望暴露的变量、函数、对象等导出给其结构使用;也可以通过某种方式,导入另外结构中的变量、函数、对象等;上面说提到的结构,就是模块;按照这种结构划分开发程序的过程,就是模块化开发的过程;无论你多么喜欢JavaScript,以及它现在发展的有多好,它都有很多的缺陷:比如

  • 虚拟机如何配置yum源_rhel7配置本地yum源

    虚拟机如何配置yum源_rhel7配置本地yum源openEuler虚拟机配置yum源开始1、首先查看系统内核情况uname-a得知内核是aarch642、查看原yum源cd/etc/yum.repos.d/catopenEuler_aarch64.repo3、下面开始配置viopenEuler_aarch64.repo把下面这段复制下来添加进去[b…

  • java生成mysql数据库建表语句、字段、字段类型、字段注释,可实现不用mysqldump备份数据库「建议收藏」

    java生成mysql数据库建表语句、字段、字段类型、字段注释,可实现不用mysqldump备份数据库「建议收藏」使用mysqldump备份数据库也是可行的,因为每次备份的时候都需要mysqldump这个文件,我在windows备份时没问题,但是放到linux上面时,centos系统死活不认这个文件,但又不想装mysql,一气之下自己研究了个不需要mysqldump就可以备份的程序,如果看了以下代码还有不懂的地方,这个网站有我的联系方式http://www.huashuku.top/about.ht…

  • 树莓派3B+使用GPIO实现串口通信[通俗易懂]

    树莓派3B+使用GPIO实现串口通信[通俗易懂]https://www.circuits.dk/setup-raspberry-pi-3-gpio-uart/

  • 远线程注入

    远线程注入OpenProcess函数打开现有的本地进程对象。HANDLEWINAPIOpenProcess(_In_DWORDdwDesiredAccess,_In_BOOLb

    2021年12月13日
  • 蚂蚁矿机linux系统文件,蚂蚁显卡矿机G2系统一键还原教程[通俗易懂]

    蚂蚁矿机linux系统文件,蚂蚁显卡矿机G2系统一键还原教程[通俗易懂]一、还原准备工作[ol]一台办公电脑(建议win7或以上系统,配置不限)一个可以格式化的U盘(最少8G,速度不限)下载UltraISO刻录软件《uiso9_cn.exe》至桌面下载《clonezilla-live-2117-11-29-03-img.iso》文件至桌面下载《checksum64.exe》至桌面双击打开checksum64.exe,把下载下来的ISO文件移动至软件中,点击选项-&gt…

发表回复

您的电子邮箱地址不会被公开。

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