首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >如何获取洛谷的CSRF Token

如何获取洛谷的CSRF Token

作者头像
pai233
发布2022-01-12 15:04:26
发布2022-01-12 15:04:26
2.8K00
代码可运行
举报
文章被收录于专栏:pai233的专栏pai233的专栏
运行总次数:0
代码可运行

在向洛谷的API发起POST请求的时候,需要在请求头中携带一个X-CSRF-Token请求头。

获取CSRF Token

我们打开洛谷,按F12,在元素项可以找到这个:

这个就是我们所需要的CSRF Token。

提取CSRF Token

通过正则表达式,我们很轻松就能写出代码:

代码语言:javascript
代码运行次数:0
运行
复制
const axios = require("axios").default
const cookieSupporter = require("axios-cookiejar-support").default
const cookieJar = require('tough-cookie')
let jar = new cookieJar.CookieJar()
let _ = cookieSupporter(axios.create({
		baseURL: "https://www.luogu.com.cn",
		withCredentials: true,
		jar: jar
	}))
.......    
async function getToken() {
	let token=await _.get('/').then(html=>{
		var Token_REG=new RegExp(/<meta name="csrf-token" content="(.*)">/);
		var execData=Token_REG.exec(html.data)
		console.log(execData)
		return execData ? execData[1].trim():null
	})
	return token;
}

getToken()函数会获取https://www.luogu.com.cm/的网页(返回HTML),随后通过正则表达式提取出CSRF Token。

实装

我们模拟一个登陆的流程,假定showCaptcha()作用为显示验证码,并反馈用户输入的验证码。

代码语言:javascript
代码运行次数:0
运行
复制
let username = "pai233"
let password = "Pa55w0rd"
let captcha = await showCaptcha()
let loginStatus=await _.post('/api/auth/userPassLogin',{
            username,
            password,
            captcha
        },
        {
            headers: {
                'X-CSRF-TOKEN': await getToken(),
                'Referer': 'https://www.luogu.com.cn/auth/login',
                'Sec-Fetch-Dest': 'empty',
                'Sec-Fetch-Mode': 'cors',
                'Sec-Fetch-Site': 'same-origin',
                'Origin': 'https://www.luogu.com.cn/',
                'X-Requested-With': 'XMLHttpRequest'
            }
		}).catch(err=>{
			if(err.response){
				return err.response.data
			}
		})
console.log(loginStatus.status)

这时会发现API返回了400 Bad Request。原因是我们的CSRF Token不是从请求头中的Referer中获取的。

Tips:部分时间测试时发现会直接返回200 OK并登陆成功,但为防止洛谷再次修改API,建议阅读下面流程!

修改

方案一:修改Referer

因为我们需要从Referer中获取CSRF Token,所以我们可以直接修改Referer请求头:

代码语言:javascript
代码运行次数:0
运行
复制
let loginStatus=await _.post('/api/auth/userPassLogin',{
            username,
            password,
            captcha
        },
        {
            headers: {
                'X-CSRF-TOKEN': await getToken(),
                'Referer': 'https://www.luogu.com.cn/',
                'Sec-Fetch-Dest': 'empty',
                'Sec-Fetch-Mode': 'cors',
                'Sec-Fetch-Site': 'same-origin',
                'Origin': 'https://www.luogu.com.cn/',
                'X-Requested-With': 'XMLHttpRequest'
            }
		}).catch(err=>{
			if(err.response){
				return err.response.data
			}
		})
console.log(loginStatus.status)

但这样会很奇怪,我明明是要登陆的,但在首页怎么能登陆呢?都没有入口…… (账号:危)

方案二:修改getToken()的请求位置

我们可以通过传参的方式,让getToken()返回Referer中的CSRF Token。

代码语言:javascript
代码运行次数:0
运行
复制
async function getToken(referer) {
	let token=await _.get(referer).then(html=>{
		var Token_REG=new RegExp(/<meta name="csrf-token" content="(.*)">/);
		var execData=Token_REG.exec(html.data)
		console.log(execData)
		return execData ? execData[1].trim():null
	})
	return token;
}
.......
let loginStatus=await _.post('/api/auth/userPassLogin',{
            username,
            password,
            captcha
        },
        {
            headers: {
                'X-CSRF-TOKEN': await getToken('/auth/login'),
                'Referer': 'https://www.luogu.com.cn/auth/login',
                'Sec-Fetch-Dest': 'empty',
                'Sec-Fetch-Mode': 'cors',
                'Sec-Fetch-Site': 'same-origin',
                'Origin': 'https://www.luogu.com.cn/',
                'X-Requested-With': 'XMLHttpRequest'
            }
		}).catch(err=>{
			if(err.response){
				return err.response.data
			}
		})
console.log(loginStatus.status)

这样,我们就可以成功实现登录的逻辑了。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-08-262,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 获取CSRF Token
  • 提取CSRF Token
  • 实装
  • 修改
    • 方案一:修改Referer
    • 方案二:修改getToken()的请求位置
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档