LoginSignup
0
0

More than 3 years have passed since last update.

Golangのネットワーク関連ライブラリを雑多にまとめる

Last updated at Posted at 2020-02-17

Golangのネットワーク関連のライブラリを自分用にざっとメモ。

HTTPリクエストを飛ばす

簡単な方法

// リクエスト
resp, _ := http.Get("http://example.com")

// そのリスポンスをprint
defer resp.Body.close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(endpoint)

難しい方法

// request structの作成
req, _ := http.NewRequest(
    "Post",
    "https://test",
    bytes.NewBuffer([]byte("request body"),
)
// そのheaderを指定
req.Header.Add("Content-Type", "application/json")

// クライアントを初期化
var client *http.Client = &http.Client{}

// そこからリクエストを飛ばす
resp, _ := client.Do(req)

// そのリスポンスをprint
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))

エンドポイントURLをいじる


base, _ := url.Parse("https://test/mypage/")
reference, _ := url.Parse("myPicture?a=1&b=2")
endpoint := base.ResolveReference(reference).String() // URLを結合する

// クエリパラメタの確認
req, _ := http.NewRequest("GET", endpoint)
fmt.Println(q:= req.URL.Query()) // map
fmt.Println(q.Encode()) //クエリ形式の文字列

MarshalとUnmarshal

  • Marshalは構造体→JSON文字列のバイト配列
  • UnmarshalはJSON文字列のバイト配列→構造体
type Person struct {
    Name string `json:"name"`  // Marshal時のkey名をnameに
    Age int `json:"age,string"` // Marshal時valueがstringに
    Friends int `json:omitempty` // Marshal時valueがempty(0)だと無視される
    password string `json:-`   // Marshal時無視される
}

func main() {
    b := []byte{`{"name":"John", "age":25, "nickname": "Johnny"}`}
    var p Person

    // byte文字列をPerson構造体へMarshalする (属性名はCaseInsensitive)
    if err := json.Unmarshal(b, &p); err!= nil {
        fmt.Println(err)
    }

    // Person構造体をbyte文字列へUnmarshalする
    v, err := json.Marshal(p)
    fmt.Println(string(v))
}
  • Person構造体のカスタム(アン)マーシャルを定義。Person構造体に以下のメソッドが存在すると、json.Marshal(Person p)json.Unmarshal(b, &p)が呼び出された際、以下が使われる。
// カスタムマーシャル
func (p Persion) MarshalJSON() ([]byte, error) {
    // nameだけをマーシャル
    v, err := json.Marshal(&struct{
        Name string
    }{
        Name: "Mr." + p.Name,
    }
    return v, err
}


// カスタムアンマーシャル
func (p Person) UnMarshalJSON(b []byte) error {
    // まずPerson2という構造体を定義し、Person2でアンマーシャル
    type Person2 struct {
         Name string
   }
    var p2 Person2
    err := json.Unmarshal(b, &p2)

    // それを使いpに放り込む
    p.Name = "Mr. " + p2.Name
    return err
}

HMAC(Hash-based Message Authentication Code)

HMACの仕組み

  1. 事前にAPIKeySecretKey(秘密鍵=PrivateKeyではない!!!)を発行し、その両方をクライアントサイドに保存する

  2. ブラウザからサーバへ以下を送信する

    • APIKey
    • バイト配列のデータ
    • HMAC = SecretKeyを用いたハッシュ関数を利用して、2のデータを暗号化したもの。なお、HeaderのSignatureには、この暗号化で使用したハッシュ関数の種類を収納する。
    • 用いたハッシュ関数の種類(SHA-1、MD5など)
  3. サーバサイドでは以下の手順でデータが改竄されていないことを確認する

    1. APIKeyに対応するSecretKeyを取り出す
    2. HMACをそのSecretKeyでdecryptし、それが「データ」と一致するか確かめる

Golangで実装

// クライアントサイド
func main() {
    const apiKey = "api_key"
    const apiSecret = "api_secret"

    data = []byte("data")
    h := hmac.New(sha.New, []byte(apiSecret))
    h.Write(data)
    sign := hex.EncodeToString(h.Sum(nil))

    // これをハッシュ関数サーバへ送る
}

// サーバサイド
func Server() {
    // 受け取ったapiKeyとHMACで...
    apiSecret := DB[apiKey]
    h := hmac.New(sha256.New, []byte(apiSecret))
    h.Write(data)
    expectedMAC = hex.EncodeToString(h.Sum(nil))

    // これが受信したデータと一致するか確認
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0