golangの日記

Go言語を中心にプログラミングについてのブログ

Go言語 httpリクエストでクッキーを使ったログイン

golang.png


はてなブログに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-Typeapplication/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)
}