上面两种认证方式其实都是通过Authenticate传参数,只不过定义不同罢了。要是自己写Web服务,两边约定好。
想怎么定义都行,当然其它web服务器就不认得了。
我把测试基本认证和加了层AES加密的基本认证的部分实现贴一下:
启动Web服务
func main() {
fmt.Println("HTTP认证 服务端 ")
http.HandleFunc("/", lib.MakeHandleFunc(lib.HTTPGET, lib.HandleTest))
log.Fatal(http.ListenAndServe(":8080", nil))
}
在这作认证
/**
HTTP身份认证测试
转Handler函数
Author: XiongChuanLiang
Date:2015-10-28
*/
package lib
import (
"log"
"net/http"
)
type HandleFuncType func(http.ResponseWriter, *http.Request)
const (
HTTPGET = "GET"
HTTPPOST = "POST"
)
func MakeHandleFunc(fMethod string, f HandleFuncType) HandleFuncType {
return func(w http.ResponseWriter, r *http.Request) {
defer func() {
if x := recover(); x != nil {
log.Printf("[%v] panic: %v", r.RemoteAddr, x)
}
}()
if r.Method != fMethod {
http.Error(w, "调用方法出错.", http.StatusMethodNotAllowed)
} else {
//if BasicAuth(r) {
if AesBasicAuth(r) {
f(w, r)
} else {
http.Error(w, "Auth失败.", http.StatusBadRequest)
}
}
}
}
// 标准的Http身份认证
func BasicAuth(r *http.Request) bool {
auth := strings.SplitN(r.Header["Authorization"][0], " ", 2)
log.Println("[BasicAuth] auth:", auth)
if len(auth) != 2 || auth[0] != "Basic" {
log.Println("[BasicAuth] [ERROR] Authorization参数传过来的格式不对!")
return false
}
payload, _ := base64.StdEncoding.DecodeString(auth[1])
fmt.Println("[BasicAuth] Auth payload:", string(payload))
userInfo := strings.SplitN(string(payload), ":", 2)
if len(userInfo) != 2 {
log.Println("[BasicAuth] [ERROR] Authorization参数少了!")
return false
}
//检验身份
return Validate(userInfo[0], userInfo[1])
}
// 如果只是设Web Api可用,不适应于网页.
// Client:将user:password用AES加密后,再用Base64发送过来
// Server:Base64解密,AES解密
func AesBasicAuth(r *http.Request) bool {
auth := strings.SplitN(r.Header["Authorization"][0], " ", 2)
log.Println("[AesBasicAuth] auth:", auth)
if len(auth) != 2 || auth[0] != "Basic" {
log.Println("[AesBasicAuth] [ERROR] Authorization参数传过来的格式不对!")
return false
}
payload := strings.TrimSpace(auth[1])
uDec, _ := base64.URLEncoding.DecodeString(payload)
origData2, err2 := util.AesDecrypt(uDec, util.AesKey16)
if err2 != nil {
panic(err2)
}
log.Println("[AesBasicAuth] origData:", string(origData2))
loginInfo := strings.SplitN(string(origData2), ":", 2)
if len(loginInfo) != 2 {
log.Println("[AesBasicAuth] [ERROR] Authorization参数少了!")
return false
}
//检验身份
return Validate(loginInfo[0], loginInfo[1])
}
/**
HTTP身份认证测试
客户端
Author: XiongChuanLiang
Date:2015-10-28
*/
package main
import (
"bytes"
"encoding/base64"
"fmt"
"io/ioutil"
"log"
"net/http"
"net/url"
"strings"
"../util"
)
var (
User string = "xcl"
Pwd string = "pwd"
TestUrl string = "http://localhost:8080/test?cmdtype=testauth&p1=xcl" //get
)
func main() {
fmt.Println("HTTP认证 客户端")
testBaseAuth()
//testAesBaseAuth()
}
// 标准的Http身份认证
func testBaseAuth() {
client := &http.Client{}
body := bytes.NewBuffer([]byte("Hello"))
req, _ := http.NewRequest("GET", TestUrl, body)
req.Header.Set("Content-Type", "application/json;charset=utf-8")
req.SetBasicAuth(User, Pwd)
resp, err := client.Do(req)
if err != nil {
fmt.Println("[testBaseAuth] err:", err)
return
}
defer resp.Body.Close()
data, _ := ioutil.ReadAll(resp.Body)
fmt.Println("[testBaseAuth] resp.Body:", string(data))
}
// 如果只是设Web Api可用,不适应于网页.
// Client:将user:password用AES加密后,再用Base64发送过来
// Server:Base64解密,AES解密
func testAesBaseAuth() {
client := &http.Client{}
body := bytes.NewBuffer([]byte("Hello"))
req, _ := http.NewRequest("GET", TestUrl, body)
req.Header.Set("Content-Type", "application/json;charset=utf-8")
//
f1 := func() string {
auth := fmt.Sprintf("%s:%s", User, Pwd)
//test
//uEnc := base64.URLEncoding.EncodeToString([]byte(auth))
if aesData, err := util.AesEncrypt([]byte(auth), util.AesKey16); err != nil {
panic(err)
} else {
return base64.URLEncoding.EncodeToString(aesData)
}
}
//自己构建Authorization
//Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
req.Header.Set("Authorization", fmt.Sprintf("Basic %s", f1()))
//
resp, err := client.Do(req)
if err != nil {
fmt.Println("[testAesBaseAuth] err:", err)
return
}
defer resp.Body.Close()
data, _ := ioutil.ReadAll(resp.Body)
fmt.Println("[testAesBaseAuth] resp.Body:", string(data))
}
上面是测试的部份代码,纯只是验证下而已,实际中估计很少有人这么做。
BLOG:http://blog.csdn.net/xcl168