目录

down-csrf-token改造记录

前端代码:

<head>
<script>
async function getCsrfToken() {
    const response = await fetch('/get_csrf_token');
    if (!response.ok) {
        throw new Error('Failed to fetch CSRF token');
    }
    const { csrf_token } = await response.json();
    return csrf_token;
}

window.addEventListener('DOMContentLoaded', async () => {
    const csrfToken = await getCsrfToken();
    document.querySelector('input[name="my_csrf_token"]').value = csrfToken;
});
</script>
.....
</head>
.....
<div id="container" class="mdui-card mdui-center">
<form id="form_url"   >
  <label for="video_link"> </label>
  <input type="text" id="video_link" name="video_link" onfocus="this.value=''"  value="请输入视频页面url 比如: https://v.test.com/UGQaf5o/" style="color: gray;">
  <input type="hidden" name="my_csrf_token" value="">
  <button id="download_btn" type="submit">Download</button>
  <p id="error_message" style="display:none">Uh-Oh! 可能是没有,请更换url</p>
</form>
</div>
.....
<script>
document.getElementById("download_btn").addEventListener("click", async function() {
    event.preventDefault(); // 阻止表单默认提交行为
    document.getElementById("download_btn").innerText = "Downloading...";
    document.getElementById("download_btn").setAttribute("disabled", "disabled");

    const v = document.getElementById('video_link').value;
    let regex;
	if (v.includes("test")) {
	  regex = /http[s]?:\/\/[\w.]+[\w\/]*[\w.]*\??[\w=&:\-\+\%]*[/]*/;
	} else if (v.includes("test")) {
	   regex = /http[s]?:\/\/[\w.]+\/@[\w.-]+\/video\/\d+/;
    }
    const video_link = v.match(regex)[0];

    const csrftoken = document.querySelector('input[name="my_csrf_token"]').value;
    const formData = new FormData();
    formData.append('video_link', video_link);
    formData.append('my_csrf_token', csrftoken); // csrf_token作为表单数据发送

    try {
        const response = await fetch('/download', {
            method: 'POST',
            body: formData
        });

        if (!response.ok) {
            document.getElementById("error_message").style.display = "block";
            download_btn.innerText = "Download";
            download_btn.removeAttribute("disabled");
            return;
        }

        const jsonData = await response.json();

        // Remove  form_url 
        document.getElementById("form_url").style.display = "none";

        // create and add the thumbnail image
        const thumb = document.createElement("img");
        const imageDiv = document.createElement("div");
        thumb.src = jsonData.thumb;
        thumb.classList.add("thumb-img");
        imageDiv.classList.add("mdui-card-media");
        imageDiv.appendChild(thumb);
		.....
</script>

后端代码:


from flask import Flask, request, jsonify, render_template_string
import requests
import json
import qrcode
from fake_useragent import UserAgent
from subprocess import run, PIPE

from flask_wtf.csrf import CSRFProtect, generate_csrf, CSRFError
from werkzeug.exceptions import BadRequest

app = Flask(__name__)

app.config['SECRET_KEY'] = '3D6SWx9deteds1'  #随机密钥
csrf = CSRFProtect(app)  # 初始化CsrfProtect

@app.errorhandler(CSRFError)
def handle_csrf_error(e):
    return jsonify({"error": e.description}), 400

@app.route('/get_csrf_token', methods=['GET'])
def get_csrf_token():
    return jsonify({'csrf_token': generate_csrf()})
    
#################################download start #################################
# 移除豁免装饰器 @csrf.exempt  #如果不删除这个  400报错  Missing CSRF token
@app.route("/download", methods=["POST"])
def download():
    csrf_token = request.form.get('my_csrf_token')  # 假设CSRF令牌通过表单字段发送
    if not csrf_token:
        return jsonify({"error": "Missing CSRF token"}), 400
        
    
    video_link = request.form.get("video_link")  # 从表单数据中获取video_link
    if not video_link:
        return jsonify({"error": "Video link is required"}), 400
	.....	

csrf版本: /home/wwwroot/down/douyin/en/indexnot-csrf.html

怎样在下面给你的前后端代码的基础上 实现 https://analyse.layzz.cn/lyz/getAnalyse?token=uuic-qackd-fga-test 这个的功能呢。 比如 https://v.test.com/download?token=uuic-qackd-fga-test 如果请求后 次数不足返回 { “code”: “0002”, “method”: null, “message”: “您的次数不足 请联系作者微信 123456” } 假如请求成功。 返回之前的json 。可以使用的总次数减1. 你可以假定 uuic-qackd-fga-test 的信息暂时保存在txt文件中或者字典里面 。格式为: 假如存入字典 1 100 1 ] 1级【token种类 1为测试 2为正式】 100【为使用的次数】 1【1为可用 0为不可用】 前端代码:

<head>
<script>
async function getCsrfToken() {
    const response = await fetch('/get_csrf_token');
    if (!response.ok) {
        throw new Error('Failed to fetch CSRF token');
    }
    const { csrf_token } = await response.json();
    return csrf_token;
}

window.addEventListener('DOMContentLoaded', async () => {
    const csrfToken = await getCsrfToken();
    document.querySelector('input[name="my_csrf_token"]').value = csrfToken;
});
</script>
.....
</head>
.....
<div id="container" class="mdui-card mdui-center">
<form id="form_url"   >
  <label for="video_link"> </label>
  <input type="text" id="video_link" name="video_link" onfocus="this.value=''"  value="请输入视频页面url 比如: https://v.test.com/UGQaf5o/" style="color: gray;">
  <input type="hidden" name="my_csrf_token" value="">
  <button id="download_btn" type="submit">Download</button>
  <p id="error_message" style="display:none">Uh-Oh! 可能是没有,请更换url</p>
</form>
</div>
.....
<script>
document.getElementById("download_btn").addEventListener("click", async function() {
    event.preventDefault(); // 阻止表单默认提交行为
    document.getElementById("download_btn").innerText = "Downloading...";
    document.getElementById("download_btn").setAttribute("disabled", "disabled");

    const v = document.getElementById('video_link').value;
    let regex;
	if (v.includes("test")) {
	  regex = /http[s]?:\/\/[\w.]+[\w\/]*[\w.]*\??[\w=&:\-\+\%]*[/]*/;
	} else if (v.includes("test")) {
	   regex = /http[s]?:\/\/[\w.]+\/@[\w.-]+\/video\/\d+/;
    }
    const video_link = v.match(regex)[0];

    const csrftoken = document.querySelector('input[name="my_csrf_token"]').value;
    const formData = new FormData();
    formData.append('video_link', video_link);
    formData.append('my_csrf_token', csrftoken); // csrf_token作为表单数据发送

    try {
        const response = await fetch('/download', {
            method: 'POST',
            body: formData
        });

        if (!response.ok) {
            document.getElementById("error_message").style.display = "block";
            download_btn.innerText = "Download";
            download_btn.removeAttribute("disabled");
            return;
        }

        const jsonData = await response.json();

        // Remove  form_url 
        document.getElementById("form_url").style.display = "none";

        // create and add the thumbnail image
        const thumb = document.createElement("img");
        const imageDiv = document.createElement("div");
        thumb.src = jsonData.thumb;
        thumb.classList.add("thumb-img");
        imageDiv.classList.add("mdui-card-media");
        imageDiv.appendChild(thumb);
		.....
</script>

后端代码:

from flask import Flask, request, jsonify, render_template_string
import requests
import json
import qrcode
from fake_useragent import UserAgent
from subprocess import run, PIPE

from flask_wtf.csrf import CSRFProtect, generate_csrf, CSRFError
from werkzeug.exceptions import BadRequest

app = Flask(__name__)

csrf = CSRFProtect(app)  # 初始化CsrfProtect

@app.errorhandler(CSRFError)
def handle_csrf_error(e):
    return jsonify({"error": e.description}), 400

@app.route('/get_csrf_token', methods=['GET'])
def get_csrf_token():
    return jsonify({'csrf_token': generate_csrf()})
    
#################################download start #################################
# 移除豁免装饰器 @csrf.exempt  #如果不删除这个  400报错  Missing CSRF token
@app.route("/download", methods=["POST"])
def download():
    csrf_token = request.form.get('my_csrf_token')  # 假设CSRF令牌通过表单字段发送
    if not csrf_token:
        return jsonify({"error": "Missing CSRF token"}), 400
        
    
    video_link = request.form.get("video_link")  # 从表单数据中获取video_link

ok  

使用程序 获取csrf cookie 。 然后构造请求 把csrf cookie 带入 请求。 不过,有一个要注意的安全隐患:任何人都能获取CSRF令牌并发送请求。如果你的网站有些敏感操作,你可能需要对其进行额外的保护,简单的CSRF防护可能是不够的。这种情况下,你可能需要添加一些额外的措施,比如: 验证码:在敏感操作需要用户输入验证信息,例如短信验证码或邮箱链接等。 第二步验证:例如使用短信、邮件或者安全问题要求用户再次确认操作。 操作频率限制:比如同一用户(基于IP或者账号判断)一段时间内只允许进行有限次数的操作,可以有效防止滥用。 登录校验:未注册/登录用户无法进行操作。 综上,仅仅依赖CSRF防护可能是不够的,对于安全性要求高的操作,建议加入额外的安全措施。

如何添加验证码来增强CSRF保护? 什么是第二步验证?如何在网站上实现它? 如何设置操作频率限制以防止滥用?