Go Pentester - HTTP Servers(3)

Building Middleware with Negroni

Reasons use middleware, including logging requests, authenticating and authorizing users, and mapping resources.

 Idiomatic HTTP Middleware for Golang. https://github.com/urfave/negroni

Install the negroni package.

go get github.com/urfave/negroni

PS: How to solve the go get can not work in China. Following is the best solution so far. https://github.com/goproxy/goproxy.cn

$ go env -w GO111MODULE=on
$ go env -w GOPROXY=https://goproxy.cn,direct

Negroni example

package main

import (
	"github.com/gorilla/mux"
	"github.com/urfave/negroni"
	"net/http"
)

func main() {
	r := mux.NewRouter()
	n := negroni.Classic()
	n.UseHandler(r)
	http.ListenAndServe(":8000",n)
}

Build and execute this program.

 Create trivial middleware that prints a message and passes execution to the next middleware in the chain:

package main

import (
	"fmt"
	"github.com/gorilla/mux"
	"github.com/urfave/negroni"
	"net/http"
)

type trivial struct {
}

func (t *trivial) ServeHTTP(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
	fmt.Println("Executing trivial middleware")
	next(w, r)
}

func main() {
	r := mux.NewRouter()
	n := negroni.Classic()
	n.UseHandler(r)
	n.Use(&trivial{})
	http.ListenAndServe(":8000",n)
}

Build and test this new program.

Adding Authentication with Negroni

Use of context, which can easily pass variables between functions.  

package main

import (
	"context"
	"fmt"
	"net/http"

	"github.com/gorilla/mux"
	"github.com/urfave/negroni"
)

type badAuth struct {
	Username string
	Password string
}

func (b *badAuth) ServeHTTP(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
	username := r.URL.Query().Get("username")
	password := r.URL.Query().Get("password")
	if username != b.Username && password !=b.Password {
		http.Error(w, "Unauthorized", 401)
		return
	}
	ctx := context.WithValue(r.Context(), "username", username)
	r = r.WithContext(ctx)
	next(w, r)
}

func hello(w http.ResponseWriter, r * http.Request) {
	username := r.Context().Value("username").(string)
	fmt.Fprintf(w, "Hi %s\n", username)
}

func main() {
	r := mux.NewRouter()
	r.HandleFunc("/hello",hello).Methods("GET")
	n := negroni.Classic()
	n.Use(&badAuth{
		Username: "admin",
		Password: "password",
	})
	n.UseHandler(r)
	http.ListenAndServe(":8000", n)

}

Build and excute this program. Then test it by sending a few requests to the server.

curl -i http://localhost:8000/hello
curl -i 'http://localhost:8000/hello?username=admin&password=password'

 Logs on the server-side.

猜你喜欢

转载自www.cnblogs.com/keepmoving1113/p/12442563.html