Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What is going on with this article?
@kudojp

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

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
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
0
Help us understand the problem. What is going on with this article?