Go言語 httpリクエストでクッキーを使ったログイン
はてなブログにHTTPリクエストでログイン(OAuth認証やBasic認証ではなくクッキーを使ったやつ)
はてなのログインページ https://www.hatena.ne.jp/login
のフォームの部分
<form action="/login" method="post"> <div> <div class="input-item"> <div class="input-item-inner"> <input autofocus="autofocus" placeholder="はてなID または メールアドレス" name="name" class="text" id="login-name" pattern=".{3,}" required="required" type="text" value=""> </div> </div> <div class="input-item"> <div class="input-item-inner"> <input type="password" value="" required="required" class="password" name="password" placeholder="パスワード"> </div> </div> <div id="option" class="config-button"> <div class="auto-login"> <a href="#" class="checkbox-tab"><label for="auto_login"></label></a> <div class="checkbox-item"> <input value="1" type="checkbox" id="auto_login" name="persistent" class="checkbox on" checked="checked"> <label for="auto_login" class="checkbox-text"> <span>次回から自動的にログイン</span> </label> </div> </div> <input name="location" value="https://blog.hatena.ne.jp/" type="hidden"> <input class="submit-button" value="送信する" type="submit"> </div> </div> </form>
クッキージャーを有効にして、フォームにある項目をリクエストヘッダーにセットする。Content-Type
を application/x-www-form-urlencoded
にして送信。
package main import ( "fmt" "io/ioutil" "log" "net/http" "net/http/cookiejar" "net/url" "strings" ) func main() { jar, err := cookiejar.New(&cookiejar.Options{}) if err != nil { log.Fatal(err) } // クッキージャーをセットしておく http.DefaultClient.Jar = jar // formのactionのURL rawurl := "https://www.hatena.ne.jp/login" values := url.Values{} // inputのname="name"の部分 ユーザー名 values.Set("name", "username") // inputのname="password"の部分 パスワード values.Set("password", "password") // inputのname="location"の部分 リダイレクト後のURL values.Set("location", "https://blog.hatena.ne.jp/") // location=https%3A%2F%2Fblog.hatena.ne.jp%2F&name=username&password=password body := strings.NewReader(values.Encode()) req, err := http.NewRequest(http.MethodPost, rawurl, body) if err != nil { log.Fatal(err) } req.Header.Set("Content-Type", "application/x-www-form-urlencoded") resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } fmt.Println(resp.Request.Response.StatusCode) // 302 fmt.Println(resp.StatusCode) // 200 fmt.Println(resp.Request.URL.String()) // ログインが成功したときのURLは https://blog.hatena.ne.jp/?_www_via=login になる // 失敗した場合は https://www.hatena.ne.jp/login のまま defer resp.Body.Close() ioutil.ReadAll(resp.Body) }