Golang에서 쿠키를 파일로 저장하는 방법

13122 단어 cookiego
Go의 cookiejar에는 쿠키를 유지하는 기능이 없으므로 쿠키를 로컬 파일에 저장하려면 something을 수행해야 합니다. 쉽게 하려면 juju/persistent-cookiejar을 대신 사용할 수 있습니다.


부적 / 영구 쿠키병


cookiejar는 저장된 쿠키의 직렬화를 허용하는 net/http/cookiejar의 포크입니다.




용법



net/http/cookiejar와 동일하게 사용할 수 있으며 쿠키를 Save로 저장할 수 있습니다.

jar, _ := cookiejar.New(nil)
http.DefaultClient.Jar = jar

// Some tasks

jar.Save()


저장할 위치는 사용자가 입력한 옵션에 따라 결정됩니다New. 기본적으로 $GOCOOKIES 또는 $HOME/.go-cookies로 설정됩니다. 파일이 존재하지 않으면 오류를 반환하지 않고 저장할 때 파일을 생성합니다.

jar, _ := cookiejar.New(&cookiejar.Options{Filename: "path/to/cookie"})


사용해보기



이것은 AtCoder에 로그인하기 위한 샘플 프로그램입니다. 이미 로그인한 경우 Already logged in!가 출력되고, 아직 로그인하지 않은 경우 사용자 이름과 암호를 묻습니다.

암호

일부 오류 처리가 생략되었습니다.

package main

import (
    "fmt"
    "log"
    "net/http"
    "net/url"
    "os"
    "strings"

    "github.com/PuerkitoBio/goquery"
    "github.com/juju/persistent-cookiejar"
    "golang.org/x/term"
)

func main() {
    jar, _ := cookiejar.New(nil)
    http.DefaultClient.Jar = jar
    defer jar.Save()

    // If the file exists, check whether logged in
    _, err := os.Stat(cookiejar.DefaultCookieFile())
    if err == nil {
        doc, _ := getDocument("https://atcoder.jp/home")
        navbarRight := doc.Find("div#navbar-collapse > ul.navbar-right")
        if navbarRight.Children().Length() == 2 {
            fmt.Println("Already logged in!")
            return
        }
    }

    var username string
    fmt.Print("Username: ")
    fmt.Scan(&username)

    fmt.Print("Password: ")
    // Don't press ctrl+c while Go reads password because your terminal won't display any inputs after that.
    // To resolve it, see gist.github.com/montanaflynn/5ae3eeae7212b0ba232f46e88f1ab67f
    bypePassword, _ := term.ReadPassword(int(os.Stdin.Fd()))

    loginUrl := "https://atcoder.jp/login"
    doc, _ := getDocument(loginUrl)
    token, found := doc.Find(`form input[type="hidden"]`).Attr("value")
    if !found {
        log.Fatal("error: cannot find CSRF token")
    }

    values := url.Values{
        "username":   {username},
        "password":   {string(bypePassword)},
        "csrf_token": {token},
    }
    req, _ := http.NewRequest("POST", loginUrl, strings.NewReader(values.Encode()))
    req.Header.Set("Content-Type", "application/x-www-form-urlencoded")

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

    if resp.Request.URL.String() == loginUrl {
        log.Fatal("Failed to login. Check your username/password")
    }

    fmt.Println("Successfully logged in!")
}

func getDocument(url string) (*goquery.Document, error) {
    resp, err := http.Get(url)
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()

    return goquery.NewDocumentFromReader(resp.Body)
}



이제 쿠키를 파일로 찾을 수 있습니다.

$ cat ~/.go-cookies
[{"Name":"REVEL_SESSION","Value":"xxxxx...","Domain":"atcoder.jp","Path":"/","Secure":true,"HttpOnly":true,"Persistent":true,"HostOnly":true,"Expires":"2022-09-13T18:19:25.9840269+09:00","Creation":"2022-03-17T18:19:15.4703732+09:00","LastAccess":"2022-03-17T18:19:25.9840269+09:00","Updated":"2022-03-17T18:19:25.9840269+09:00","CanonicalHost":"atcoder.jp"}]


파일이 존재할 때 다시 실행하면,

$ go run main.go
Already logged in!


사용자 이름/비밀번호를 묻지 않습니다.

좋은 웹페이지 즐겨찾기