赞
踩
之前写的《golang实现一个简单的HTTP server》没有包含认证部分
本例给出了支持BasicAuth的实现,以及如何在一个项目中导入自己定义的package
admin@hpc-1:~/go$ mkdir auth_http
admin@hpc-1:~/go$ cd auth_http
admin@hpc-1:~/go/auth_http$
admin@hpc-1:~/go/auth_http$ go mod init my_auth
go: creating new go.mod: module my_auth
admin@hpc-1:~/go/auth_http$
admin@hpc-1:~/go/auth_http$ cat go.mod
module my_auth
go 1.18
admin@hpc-1:~/go/auth_http$
admin@hpc-1:~/go/auth_http$ tree
.
├── go.mod
├── http_rpc_server.go
└── utils
└── do_auth.go
1 directory, 3 files
admin@hpc-1:~/go/auth_http$
admin@hpc-1:~/go/auth_http$ cat http_rpc_server.go package main import ( "fmt" "log" "flag" "net/http" "encoding/json" "my_auth/utils" ) // 定义一个用于接收请求的结构体 type MapPrinter struct{} // 定义一个用于接收请求的方法 func (m *MapPrinter) PrintMap(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) return } // 检查认证头部信息 username, password, ok := r.BasicAuth() if !ok { // 未提供基本身份验证,返回 401 Unauthorized w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`) w.WriteHeader(http.StatusUnauthorized) fmt.Fprintln(w, "401 Unauthorized") return } // 验证用户名和密码 if !utils.CheckCredentials(username, password) { // 用户名和密码不匹配,返回 401 Unauthorized w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`) w.WriteHeader(http.StatusUnauthorized) fmt.Fprintln(w, "401 Unauthorized") return } var payload map[string]interface{} err := json.NewDecoder(r.Body).Decode(&payload) if err != nil { http.Error(w, "Invalid payload", http.StatusBadRequest) return } fmt.Println("Received payload:") for key, value := range payload { fmt.Printf("%s: %v\n", key, value) } w.WriteHeader(http.StatusOK) w.Write([]byte("Map printed successfully\n")) } func main() { //获取监听端口,默认8080 port := flag.String("p", "8080", "指定监听端口") // 解析命令行参数 flag.Parse() //注册abc-api路由 http.HandleFunc("/abc-api", new(MapPrinter).PrintMap) admin@hpc-1:~/go/auth_http$ admin@hpc-1:~/go/auth_http$ admin@hpc-1:~/go/auth_http$ admin@hpc-1:~/go/auth_http$ cat utils/do_auth.go package utils func CheckCredentials(username, password string) bool { validUsername := "admin" validPassword := "admin" return username == validUsername && password == validPassword } admin@hpc-1:~/go/auth_http$
go mode init <package_name>
是将代码从GOPATH 模式迁移到模块模式。然后使用模块路径来导入其他模块或包package main
开头func main()
作为程序执行的入口utils
目录下的所有文件(本例中只有do_auth.go一个文件)都以package utils
开头,表明这些文件都属于utils
这个自定义包的组成部分以大写字母开头
,例如本例中的CheckCredentialsutils
中的函数的时候
import "my_auth/utils"
,就是由init时候创建的模块加上"/",再加上自定义的package nameutils
里面的函数的时候,使用utils.Xxxxx来调用,此时和那个函数具体写在哪个文件中就没有关系了(本例中调用时候就不会出现do_auth这个文件名)admin@hpc-1:~/go/auth_http$ go build -o http_rpc_server
admin@hpc-1:~/go/auth_http$
admin@hpc-1:~/go/auth_http$ file http_rpc_server
http_rpc_server: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, Go BuildID=jj_W4SsJdLxNOWHH706-/p8kU3nvIDJ1cRjEIGWFi/752lBQWnErUy3P6gdHgN/2ksEePP3sNj-He57uoCu, not stripped
admin@hpc-1:~/go/auth_http$
admin@hpc-1:~/go/auth_http$ chmod +x http_rpc_server
admin@hpc-1:~/go/auth_http$
admin@hpc-1:~/go/auth_http$ ./http_rpc_server -p 8090
Server is listening on port %s... 8090
admin@hpc-1:~/go/auth_http$ curl -X POST -H "Content-Type: application/json" -d '{"key1":"value1", "key2":"value2"}' http://localhost:8090/abc-api
401 Unauthorized
admin@hpc-1:~/go/auth_http$
admin@hpc-1:~/go/auth_http$ curl -X POST -u admin:password -H "Content-Type: application/json" -d '{"key1":"value1", "key2":"value2"}' http://localhost:8090/abc-api
401 Unauthorized
admin@hpc-1:~/go/auth_http$
admin@hpc-1:~/go/auth_http$ curl -X POST -u admin:admin -H "Content-Type: application/json" -d '{"key1":"value1", "key2":"value2"}' http://localhost:8090/abc-api
Map printed successfully
admin@hpc-1:~/go
admin@hpc-1:~/go/auth_http$ ./http_rpc_server -p 8090
Server is listening on port %s... 8090
Received payload:
key1: value1
key2: value2
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。