首页 > 解决方案 > 如何使用 HttpOnly cookie

问题描述

我理解了 cookie httpOnly 的目的,这个系统对 cookie 仍然是安全的,因为我们不能使用 document.cookie 来获取 cookie 信息(例如 XSS 攻击)。

我用烧瓶和 PHP 做了一个 POC 来实践这个概念。

  1. 我发出了一个 POST 请求,服务器使用 httpOnly 创建了 response.set_cookie:
@app.route('/api/connexion', methods=['POST'])
def conn():
    login = request.form["login"]
    password = request.form["password"]
    response = make_response(jsonify({
        'login':login,
        'password': password
    }))
    response.set_cookie('token', 't1',httponly=True)
    return response
  1. 使用 php 代码,我发送请求并获得响应,但是如何保存 cookie 以在其他请求中与其他 API 调用重用?

php代码:

myForm = document.getElementById("myForm")
    myForm.addEventListener('submit', (e) => {
        console.log("in event");
        e.preventDefault();
        let form = new FormData(myForm);
        fetch("http://127.0.0.1:8000/api/connexion",{
            method:'POST',
            body:form
        }).then((response) => {
            return response.json();
        }).then((text)=> {
            console.log(text);
        })

    })

所以问题是:我是否需要获取 cookie 并手动保存,否则 cookie 将在每个请求中自动发送,我想了解如何。

非常感谢。

标签: xsshttpcookies

解决方案


只要日期在未来,浏览器就会自动保存 cookie。一旦过了日期,浏览器就会“抛出” cookie 并停止使用它。在 cookie中添加过期日期是一个好习惯

浏览器保存 cookie 后,会在大部分请求中将其发送到 cookie 中指定的域。

在您的示例中 - 浏览器不会发送您刚刚定义的新令牌 cookie。那是因为fetch规范,您可以在凭据下查看。

如何使用获取请求自动发送域 cookie

当您创建新的 fetch 请求时,请确保您有{"credentials":"same-origin"}init 对象。

在您的代码中,这应该如下所示:
myForm = document.getElementById("myForm")
myForm.addEventListener('submit', (e)=>{
    console.log("in event");
    e.preventDefault();
    let form = new FormData(myForm);
    let fetchInitObject = {
        method: 'POST',
        body: form,
        /*
        The following line will tell the browser 
        to send all the cookies of the site in the URL, as long as 
        the url and the site that runs the Javascript code are from the same origin
        In your example - the side that runs the javascript code, should be 127.0.0.1 in port 8000, without http
        */
        credentials: 'same-origin'
    };
    fetch("http://127.0.0.1:8000/api/connexion", fetchInitObject).then((response)=>{
        return response.json();
    }
    ).then((text)=>{
        console.log(text);
    }
    )

}
)

推荐阅读