如何使用登录数据发送GET请求并将Cookie数据保存到txt文件中?

huangapple go评论86阅读模式
英文:

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

问题

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

我有一个curl数据:

-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内容如下:

```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中。

英文:

I want to send a GET request with login data and save cookie data to txt file.

I had a curl data

   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

I need to convert this curl to Go; I have tried online converter, it's giving error and I don't think they have any capability to store cookies to txt file.

I had a sample Go file which doesn't have a capability to send username and password, but I think it does saves cookies.txt file:

My main.go contents:

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)
}

I need to mainly convert and add this curl flag and data --data-raw 'username=admin&password=pasxxord7' to Go.

答案1

得分: 2

当你使用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请求不用于在请求体中传输数据,所以当使用data-raw时,curl自动使用POST是正确的。

根据你的示例头部和data-raw的数据,看起来你正在使用表单值,也可以这样指定:

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

这将添加content-typemultipart/form-data的头部,并自动发送为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)
	}

	// 省略其他头部以保持简洁。
	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,但如果你添加你的其他头部,它应该是完整的。

你不需要使用Cookie Jar,因为它用于存储和发送出站请求的cookie。看起来你只对存储从服务器返回的cookie感兴趣,所以你需要在响应上调用.Cookies()方法并使用返回的结果。

英文:

When you use the curl flag --data-raw is sends a POST request. You can verify this by using the verbose output flag -v, for example:

$ curl -c cookies.txt &#39;http://requestbin.net/r/40vmgerp&#39; \
  -H &#39;sec-ch-ua: &quot; Not A;Brand&quot;;v=&quot;99&quot;, &quot;Chromium&quot;;v=&quot;98&quot;&#39; \
  -H &#39;sec-ch-ua-mobile: ?1&#39; \
  -H &#39;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&#39; \
  -H &#39;Content-type: application/x-www-form-urlencoded; charset=UTF-8&#39; \
  -H &#39;Accept: text/javascript, text/html, application/xml, text/xml, */*&#39; \
  -H &#39;Referer: http://localhost:8080/&#39; \
  -H &#39;X-Requested-With: XMLHttpRequest&#39; \
  -H &#39;sec-ch-ua-platform: &quot;Android&quot;&#39; \
  --data-raw &#39;username=admin&amp;password=pasxxord7&#39; \
  --compressed -v

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

Generally GET requests are not used for transmitting data in the body so using a POST as curl does automatically when data-raw is given is correct.

Based on your example headers and data for data-raw it appears you are using form values which can also be specified as:

curl localhost -F &#39;username=admin&#39; -F &#39;password=pasxxord7&#39;

This would add the content-type multipart/form-data header and send as POST automatically. This has the advantage of doing any necessary escaping as well.


To recreate your curl request in Go would be as follows:

package main

import (
	&quot;encoding/json&quot;
	&quot;fmt&quot;
	&quot;net/http&quot;
	&quot;net/url&quot;
	&quot;os&quot;
	&quot;strings&quot;
)

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

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

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

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

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

	cookies := resp.Cookies()

	if len(cookies) &gt; 0 {
		cookieFile, err := os.Create(&quot;cookies.txt&quot;)
		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(&quot;No cookies found.&quot;)
	}
}

Note the example above uses RequestBin rather than localhost but should otherwise be complete if you add your other headers.

You don't need to use a Cookie Jar because that is used to store and send cookies with an outgoing request. It appears you are only interested in storing the cookies sent back from the server and so you need to call the .Cookies() method on the response and use what is returned.

huangapple
  • 本文由 发表于 2022年3月12日 03:00:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/71443468.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定