secure.go shows the logic for the simple server. It has been divided into four functions:
- The requestHandler function to respond to incoming HTTP requests.
- The isAuthorized function to check if the incoming request is authorized.
- The getAuthorizedUser function to check if the token has an associated user. If the token does not have an associated user, then the token is considered to be invalid.
- The main function to start the server.
Now let's look at the code:
// secure/secure.go package main import ( "fmt" "log" "net/http" "strings" ) var authTokens = map[string]string{ "AUTH-TOKEN-1": "User 1", "AUTH-TOKEN-2": "User 2", } // getAuthorizedUser tries to retrieve user for the given token. func getAuthorizedUser(token string) (string, error) { var err error user, valid := authTokens[token] if !valid { err = fmt.Errorf("Auth token '%s' does not exist.", token) } return user, err } // isAuthorized checks request to ensure that it has Authorization header // with defined value: "Bearer AUTH-TOKEN" func isAuthorized(r *http.Request) bool { rawToken := r.Header["Authorization"] if len(rawToken) != 1 { return false } authToken := strings.Split(rawToken[0], " ") if !(len(authToken) == 2 && authToken[0] == "Bearer") { return false } user, err := getAuthorizedUser(authToken[1]) if err != nil { log.Printf("Error: %s", err) return false } log.Printf("Successful request made by '%s'", user) return true } var success = []byte("Received authorized request.") var failure = []byte("Received unauthorized request.") func requestHandler(w http.ResponseWriter, r *http.Request) { if isAuthorized(r) { w.Write(success) } else { w.WriteHeader(http.StatusUnauthorized) w.Write(failure) } } func main() { http.HandleFunc("/", requestHandler) fmt.Println("Starting server @ http://localhost:8080") http.ListenAndServe(":8080", nil) }