如何发送带有登录数据的 GET 请求并将 cookie 数据保存到 txt 文件?

How to send a GET request with login data and save cookie data to txt file?

我想发送带有登录数据的 GET 请求并将 cookie 数据保存到 txt 文件。

我有一个卷曲数据

   curl -c cookies.txt 'http://localhost:8080/api/v2/auth/login' \
  -H 'sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="98"' \
  -H 'sec-ch-ua-mobile: ?1' \
  -H 'User-Agent: Mozilla/5.0 (Linux; Android 9; BND-AL10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.106 Mobile Safari/537.36' \
  -H 'Content-type: application/x-www-form-urlencoded; charset=UTF-8' \
  -H 'Accept: text/javascript, text/html, application/xml, text/xml, */*' \
  -H 'Referer: http://localhost:8080/' \
  -H 'X-Requested-With: XMLHttpRequest' \
  -H 'sec-ch-ua-platform: "Android"' \
  --data-raw 'username=admin&password=pasxxord7' \
  --compressed

我需要将这个 curl 转换为 Go;我试过在线转换器,它出错了,我认为他们没有任何能力将 cookie 存储到 txt 文件。

我有一个示例 Go 文件,它不能发送用户名和密码,但我认为它确实保存了 cookies.txt 文件:

我的main.go内容:

package main

import "net/http/cookiejar"
import "net/http"
import "encoding/json"
import "io/ioutil"
import "fmt"

func main(){
    cookies := make(map[string][]*http.Cookie)
    jar, _ := cookiejar.New(nil)
    client := http.Client{Jar: jar}
    r, err := client.Get("http://localhost:8080/api/v2/auth/login")
    if err != nil {
        fmt.Println(err)
        return
    }
    siteCookies := jar.Cookies(r.Request.URL)
    cookies[r.Request.URL.String()] = siteCookies
    data, _ := json.Marshal(cookies)
    ioutil.WriteFile("cookies.txt", data, 0644)
}

我主要需要将这个curl标志和数据--data-raw 'username=admin&password=pasxxord7'转换并添加到Go中。

当您使用 curl 标志时,--data-raw 会发送一个 POST 请求。您可以使用详细输出标志 -v 来验证这一点,例如:

$ curl -c cookies.txt 'http://requestbin.net/r/40vmgerp' \
  -H 'sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="98"' \
  -H 'sec-ch-ua-mobile: ?1' \
  -H 'User-Agent: Mozilla/5.0 (Linux; Android 9; BND-AL10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.106 Mobile Safari/537.36' \
  -H 'Content-type: application/x-www-form-urlencoded; charset=UTF-8' \
  -H 'Accept: text/javascript, text/html, application/xml, text/xml, */*' \
  -H 'Referer: http://localhost:8080/' \
  -H 'X-Requested-With: XMLHttpRequest' \
  -H 'sec-ch-ua-platform: "Android"' \
  --data-raw 'username=admin&password=pasxxord7' \
  --compressed -v

* Connected to requestbin.net (172.67.190.62) port 80 (#0)
> POST /r/40vmgerp HTTP/1.1 <--------------------
> Host: requestbin.net
> Accept-Encoding: deflate, gzip
> sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="98"
> sec-ch-ua-mobile: ?1
...

通常 GET 请求不用于在 body 中传输数据,因此使用 POST 作为 curl 在给定 data-raw 时自动执行的操作是正确的。

根据您的示例 headers 和 data-raw 的数据,看来您使用的表单值也可以指定为:

curl localhost -F 'username=admin' -F 'password=pasxxord7'

这将添加 content-type multipart/form-data header 并自动发送为 POST。这也具有进行任何必要转义的优点。


要在 Go 中重新创建您的 curl 请求,如下所示:

package main

import (
    "encoding/json"
    "fmt"
    "net/http"
    "net/url"
    "os"
    "strings"
)

func main() {
    data := url.Values{}
    data.Set("username", "admin")
    data.Set("password", "pasxxord7")

    body := strings.NewReader(data.Encode())

    req, err := http.NewRequest(http.MethodPost, "https://requestbin.net/r/40vmgerp", body)
    if err != nil {
        panic(err)
    }

    // Omitted other headers for brevity.
    req.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
    req.Header.Set("Accept", "text/javascript, text/html, application/xml, text/xml, */*")

    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    cookies := resp.Cookies()

    if len(cookies) > 0 {
        cookieFile, err := os.Create("cookies.txt")
        if err != nil {
            panic(err)
        }
        defer cookieFile.Close()

        encoder := json.NewEncoder(cookieFile)

        for _, cookie := range cookies {
            // fmt.Fprintln(cookieFile, cookie.String()) // write plain text to file
            if err := encoder.Encode(cookie); err != nil {
                panic(err)
            }
        }
    } else {
        fmt.Println("No cookies found.")
    }
}

请注意,上面的示例使用 RequestBin 而不是 localhost,但如果您添加其他 headers,则应该是完整的。

您不需要使用 Cookie Jar,因为它用于存储和发送带有传出请求的 cookie。您似乎只对存储从服务器发回的 cookie 感兴趣,因此您需要对响应调用 .Cookies() 方法并使用返回的内容。