1. 程式人生 > >Go實戰--通過basic認證的http(basic authentication)

Go實戰--通過basic認證的http(basic authentication)

生命不止, 繼續 go go go !!!

今天就跟大家介紹一下帶有basic認證的api。

何為basic authentication

In the context of a HTTP transaction, basic access authentication is a method for a HTTP user agent to provide a user name and password when making a request.

但是這種認證方式有很多的缺點:
雖然基本認證非常容易實現,但該方案建立在以下的假設的基礎上,即:客戶端和伺服器主機之間的連線是安全可信的。特別是,如果沒有使用SSL/TLS這樣的傳輸層安全的協議,那麼以明文傳輸的金鑰和口令很容易被攔截。該方案也同樣沒有對伺服器返回的資訊提供保護。

請各位大大稍安勿躁,今天我們先介紹一下go中使用basic認證,之後會跟大家介紹更安全的認證方式 auth2.0.

那麼如何進行base64加密解密之前介紹過了:

package main

import (
    "encoding/base64"
    "fmt"
)

func main() {
    s := "heal the world, make it a better place"

    encodeStd := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
    s64 := base64.NewEncoding(encodeStd).EncodeToString([]byte
(s)) fmt.Println("base64.NewEncoding(encodeStd).EncodeToString") fmt.Println(len(s)) fmt.Println(len(s64)) fmt.Println(s) fmt.Println(s64) s64_std := base64.StdEncoding.EncodeToString([]byte(s)) fmt.Println("base64.StdEncoding.EncodeToString") fmt.Println(len(s)) fmt.Println(len
(s64_std)) fmt.Println(s) fmt.Println(s64_std) }

basic 認證形如:

Authorization: Basic ZGVtbzpwQDU1dzByZA==

這裡寫圖片描述

簡單的basic認證

strings.SplitN
記憶中,沒有詳細介紹過strings package,這裡就囉嗦這一個方法:

func SplitN(s, sep string, n int) []string

SplitN slices s into substrings separated by sep and returns a slice of the substrings between those separators. If sep is empty, SplitN splits after each UTF-8 sequence.
看到了嗎,golang中的strings包為我們提供了強大的字串處理能力。

package main

import (
    "encoding/base64"
    "net/http"
    "strings"
)

func checkAuth(w http.ResponseWriter, r *http.Request) bool {
    s := strings.SplitN(r.Header.Get("Authorization"), " ", 2)
    if len(s) != 2 {
        return false
    }

    b, err := base64.StdEncoding.DecodeString(s[1])
    if err != nil {
        return false
    }

    pair := strings.SplitN(string(b), ":", 2)
    if len(pair) != 2 {
        return false
    }

    return pair[0] == "user" && pair[1] == "pass"
}

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        if checkAuth(w, r) {
            w.Write([]byte("hello world!"))
            return
        }

        w.Header().Set("WWW-Authenticate", `Basic realm="MY REALM"`)
        w.WriteHeader(401)
        w.Write([]byte("401 Unauthorized\n"))
    })

    http.ListenAndServe(":8080, nil)
}

通過postman進行訪問:
這裡寫圖片描述
這裡寫圖片描述

通過第三方完成basic認證

github.com/ant0ine/go-json-rest/rest
Go-Json-Rest is a thin layer on top of net/http that helps building RESTful JSON APIs easily. It provides fast and scalable request routing using a Trie based implementation, helpers to deal with JSON requests and responses, and middlewares for functionalities like CORS, Auth, Gzip, Status …

star:2810

go get -u github.com/ant0ine/go-json-rest/rest

應用:

package main

import (
    "log"
    "net/http"

    "github.com/ant0ine/go-json-rest/rest"
)

func main() {
    api := rest.NewApi()
    api.Use(rest.DefaultDevStack...)
    api.Use(&rest.AuthBasicMiddleware{
        Realm: "my realm",
        Authenticator: func(userId string, password string) bool {
            if userId == "user" && password == "pass" {
                return true
            }E
            return false
        },
    })
    api.SetApp(rest.AppSimple(func(w rest.ResponseWriter, r *rest.Request) {
        w.WriteJson(map[string]string{"Body": "Hello World!"})
    }))
    log.Fatal(http.ListenAndServe(":8080", api.MakeHandler()))
}

通過postman進行訪問:
這裡寫圖片描述

這裡寫圖片描述