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

时间:2022-01-22 16:20:58

生命不止, 继续 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)

简单的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)
Go实战--通过basic认证的http(basic authentication)

通过第三方完成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)

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