如何使用 cURL 发送 Cookies?

427
我可以帮你进行翻译。这篇文章是关于编程的,提到了使用cURL发送cookies的问题。以下是需要翻译的内容:

我看过使用cURL发送cookies的方法,但它对我无效。

我的REST端点如下:

class LoginResource(restful.Resource):
    def get(self):
        print(session)
        if 'USER_TOKEN' in session:
            return 'OK'
        return 'not authorized', 401

当我尝试访问该端点时,它会拒绝:

curl -v -b ~/Downloads/cookies.txt -c ~/Downloads/cookies.txt http://127.0.0.1:5000/
* About to connect() to 127.0.0.1 port 5000 (#0)
*   Trying 127.0.0.1...
* connected
* Connected to 127.0.0.1 (127.0.0.1) port 5000 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.27.0
> Host: 127.0.0.1:5000
> Accept: */*
>
* HTTP 1.0, assume close after body
< HTTP/1.0 401 UNAUTHORIZED
< Content-Type: application/json
< Content-Length: 16
< Server: Werkzeug/0.8.3 Python/2.7.2
< Date: Sun, 14 Apr 2013 04:45:45 GMT
<
* Closing connection #0
"not authorized"%

我的~/Downloads/cookies.txt文件在哪里:

cat ~/Downloads/cookies.txt
USER_TOKEN=in

并且服务器收不到任何东西:

127.0.0.1 - - [13/Apr/2013 21:43:52] "GET / HTTP/1.1" 401 -
127.0.0.1 - - [13/Apr/2013 21:45:30] "GET / HTTP/1.1" 401 -
<SecureCookieSession {}>
<SecureCookieSession {}>
127.0.0.1 - - [13/Apr/2013 21:45:45] "GET / HTTP/1.1" 401 -

我错过了什么?

1
我认为添加-c选项告诉curl将你的cookie文件用作输出cookie存储器,这可能不是你想要的。 - Blender
仅使用“-b”选项也无法正常工作,仍然出现相同的错误:( - daydreamer
“-b” cookie 文件的格式不仅仅是 “var=value”,它应该与使用 “-c” 写入的 cookie jar 的格式相同。访问一个使用此选项发送 cookie 的站点,并查看生成的文件。 - Barmar
2
-b cookie_file 应该是 Netscape/Mozilla 格式或纯 HTTP 头。这是纯 http 头的示例:Set-cookie: cookie_name=cookie_value;这是最基本的。不要忘记在末尾加上分号。 - Alex
10个回答

707

这对我有效:

curl -v --cookie "USER_TOKEN=Yes" http://127.0.0.1:5000/

我能看出后端使用的价值

print(request.cookies)

20
只要您从不将用户令牌的布尔值作为 cookie 存储,因为他们可以通过其他方式进行身份验证而无需使用该方法登录。 - matts1
19
根据 man 手册,对于选项 -b, --cookie,例如 curl -b <file-or-pairs>,如果参数是一个包含 '=' 符号的字符串,则按原样传递,否则将被视为要从中读取 cookie 的文件名。 - ryenus
94
多个cookie可以用分号设置 --cookie "key1=val1;key2=val2;..." - user1329187
为了发送多个cookie,我不得不在“;”后面加上一个空格(我正在使用Mac) 例如:--cookie“key1 = val1; key2 = val2” - tharinduwijewardane

118
您可以参考https://curl.haxx.se/docs/http-cookies.html了解如何处理cookie的完整教程。您可以使用。
curl -c /path/to/cookiefile http://yourhost/

要写入cookie文件并启动引擎以及使用cookie,您可以使用以下代码:

curl -b /path/to/cookiefile  http://yourhost/

读取并启动Cookie引擎,如果不是文件,则将传递给定的字符串。


1
在我看来,你没有对官方文档进行增强,而官方文档本身非常晦涩难懂。除了“-b”标志的重载之外,-c-b之间的本质差异是什么?它们都启动引擎并指向一个cookie文件。 - nhed
8
-c 参数将信息写入 cookie 文件,-b 参数从 cookie 文件读取信息。因此,在发送登录表单的凭据时,应使用 -c 将生成的 cookie 写入文件中,然后使用 -b 从文件中读取并在下一次请求时包含该 cookie。 - Madbreaks
43
或者执行 curl -b cookiefile -c cookiefile https://yourhost/ 命令,就像浏览器一样读取和写入同一个cookie存储。 - LinuxDisciple

54

您在 cookie 文件中使用了错误的格式。正如 curl 文档所述,它使用旧版 Netscape cookie 文件格式,该格式与 Web 浏览器使用的格式不同。如果您需要手动创建一个 curl cookie 文件,这篇文章应该会对您有所帮助。在您的示例中,文件应包含以下行:

127.0.0.1   FALSE   /   FALSE   0   USER_TOKEN  in

共有7个以制表符分隔的字段,分别表示域名尾部匹配路径安全性过期时间名称


2
是的,这就是cURL的cookie格式。这些是制表符而不是空格。 - m3nda
5
应该将此标记为官方答案,因为它真正解决了 @daydreamer 的设置失败的原因。 - Valber

12

curl -H @<header_file> <host>

自从curl 7.55版本起,支持使用@<file>指定文件中的请求头信息。

echo 'Cookie: USER_TOKEN=Yes' > /tmp/cookie

将cookie信息保存到/tmp/cookie文件中:

curl -H @/tmp/cookie <host>

文档和代码提交记录


6
如果你已经在应用程序中发出了该请求,并在 Google Dev 工具中看到它被记录下来,那么你可以在网络选项卡中右键单击该请求时使用复制 cURL 命令。复制 -> 复制为 cURL。它将包含所有的头信息、cookies 等等。

如果您需要的cookie已经通过浏览器可用,那么这个解决方案会更加容易。+1 - JSuar

4

我正在使用Debian操作系统,但是无法使用波浪线(~)来表示路径。最初我尝试使用

curl -c "~/cookie" http://localhost:5000/login -d username=myname password=mypassword

我不得不将其更改为:

curl -c "/tmp/cookie" http://localhost:5000/login -d username=myname password=mypassword

-c 用于创建 cookie,-b 用于使用 cookie。

因此,我可以使用以下命令:

curl -b "/tmp/cookie" http://localhost:5000/getData

4
如果在引号内使用~,它将被视为波浪线的字面意思,而不会扩展为$HOME - Sahbi

3

使用json的另一种解决方案。

CURL:

curl -c /tmp/cookie -X POST -d '{"chave":"email","valor":"hvescovi@hotmail.com"}' -H "Content-Type:application/json" localhost:5000/set

curl -b "/tmp/cookie" -d '{"chave":"email"}' -X GET -H "Content-Type:application/json"  localhost:5000/get

curl -b "/tmp/cookie" -d '{"chave":"email"}' -X GET -H "Content-Type:application/json" localhost:5000/delete

PYTHON 代码:

from flask import Flask, request, session, jsonify
from flask_session import Session

app = Flask(__name__)

app.secret_key = '$#EWFGHJUI*&DEGBHYJU&Y%T#RYJHG%##RU&U'
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)

@app.route('/')
def padrao():
    return 'backend server-side.'
    
@app.route('/set', methods=['POST'])
def set():
    resposta = jsonify({"resultado": "ok", "detalhes": "ok"})
    dados = request.get_json()  
    try:  
        if 'chave' not in dados: # não tem o atributo chave?
            resposta = jsonify({"resultado": "erro", 
                            "detalhes": "Atributo chave não encontrado"})
        else:
            session[dados['chave']] = dados['valor']
    except Exception as e:  # em caso de erro...
        resposta = jsonify({"resultado": "erro", "detalhes": str(e)})

    resposta.headers.add("Access-Control-Allow-Origin", "*")
    return resposta  

@app.route('/get')
def get():
    try:
        dados = request.get_json()  
        retorno = {'resultado': 'ok'}
        retorno.update({'detalhes': session[dados['chave']]}) 
        resposta = jsonify(retorno)
    except Exception as e:  
        resposta = jsonify({"resultado": "erro", "detalhes": str(e)})
    
    resposta.headers.add("Access-Control-Allow-Origin", "*")
    return resposta 

@app.route('/delete')
def delete():
    try:
        dados = request.get_json()  
        session.pop(dados['chave'], default=None)
        resposta = jsonify({"resultado": "ok", "detalhes": "ok"})        
    except Exception as e:  # em caso de erro...
        resposta = jsonify({"resultado": "erro", "detalhes": str(e)})
            
    resposta.headers.add("Access-Control-Allow-Origin", "*")
    return resposta  

app.run(debug=True)

1
这是正确发送cookie的示例:-H 'cookie: key1=val2; key2=val2;' cURL也提供了--cookie的便利性。运行man curltldr curl 这是从Chrome > 检查 > 网络 > 复制为cURL复制的。
curl 'https://www.example.com/api/app/job-status/' \
  -H 'authority: www.example.com' \
  -H 'sec-ch-ua: "Chromium";v="92", " Not A;Brand";v="99", "Google Chrome";v="92"' \
  -H 'sec-ch-ua-mobile: ?0' \
  -H 'user-agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.111.111 Safari/111.36' \
  -H 'content-type: application/json' \
  -H 'accept: */*' \
  -H 'origin: https://www.example.com' \
  -H 'sec-fetch-site: same-origin' \
  -H 'sec-fetch-mode: cors' \
  -H 'sec-fetch-dest: empty' \
  -H 'referer: https://www.example.com/app/jobs/11111111/' \
  -H 'accept-language: en-US,en;q=0.9' \
  -H 'cookie: menuOpen_v3=true; imageSize=medium;' \
  --data-raw '{"jobIds":["1111111111111"]}' \
  --compressed

0

我在 Windows 上使用 GitBash,但没有找到适合我的方法。

所以我决定将我的 cookie 保存到一个名为 .session 的文件中,并使用 cat 命令从中读取,如下所示:

curl -b $(cat .session) http://httpbin.org/cookies

如果你好奇的话,我的 cookie 长这样:

session=abc123

0

这对我有用:

curl -v -H 'cookie: _appname_session=lksjdflsdkj...; path=/; HttpOnly; SameSite=Lax' localhost:3000/

请注意,会话名称是_appname_session

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接