Go实战--通过basic认证的http(basic authentication)

生命不止, 继续 go go go !!!

之前写过相关博客:
Go实战–go中使用base64加密(The way to go)

Go实战–实现简单的restful api(The way to 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==

Go实战--通过basic认证的http(basic authentication)_第1张图片

简单的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进行访问:
Go实战--通过basic认证的http(basic authentication)_第2张图片
Go实战--通过basic认证的http(basic authentication)_第3张图片

通过第三方完成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进行访问:
Go实战--通过basic认证的http(basic authentication)_第4张图片

Go实战--通过basic认证的http(basic authentication)_第5张图片

你可能感兴趣的:(go,Go从不放弃到实战)