Middleware
This page shows how to wire go-ip-sentry into Gin or net/http, how to skip specific paths, and how to call Check directly without middleware.
Three Ways to Integrate
| Option | Signature | On failure |
|---|---|---|
HTTPMiddleware |
func (i *IPGuardian) HTTPMiddleware(next http.Handler) http.Handler |
Sets Content-Type: application/json, writes the status and {"error": "..."}, and skips next |
GinMiddleware |
func (i *IPGuardian) GinMiddleware() gin.HandlerFunc |
c.JSON(status, gin.H{"error": ...}) then c.Abort() |
Check |
func (i *IPGuardian) Check(r *http.Request, w http.ResponseWriter) IPGuardianResult |
Up to the caller |
All three have already written the session and device cookies when they pass, so they must run before the handler writes a body.
net/http
mux := http.NewServeMux()
mux.HandleFunc("/api/orders", ordersHandler)
log.Fatal(http.ListenAndServeTLS(":8443", "cert.pem", "key.pem", sentry.HTTPMiddleware(mux)))
Gin
r := gin.New()
r.Use(gin.Recovery())
api := r.Group("/api")
api.Use(sentry.GinMiddleware())
api.GET("/orders", listOrders)
if err := r.RunTLS(":8443", "cert.pem", "key.pem"); err != nil {
log.Fatal(err)
}
Keep gin.Recovery(): when Redis fails during scoring, Check panics (see Known Issues), and Recovery turns that into a 500.
Skipping Paths
Health checks, metrics scrapes, and fixed-period polling build up regular intervals and rate counts, so keep them out:
func protect(sentry *golangIPSentry.IPGuardian, next http.Handler) http.Handler {
guarded := sentry.HTTPMiddleware(next)
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case "/healthz", "/metrics":
next.ServeHTTP(w, r)
default:
guarded.ServeHTTP(w, r)
}
})
}
Calling Check Directly
When you need a custom response format (an HTML error page, for example):
func handler(sentry *golangIPSentry.IPGuardian) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
result := sentry.Check(r, w)
if !result.Success {
http.Error(w, http.StatusText(result.StatusCode), result.StatusCode)
return
}
w.Write([]byte("OK"))
}
}
IPGuardianResult.Error contains the client IP; check your privacy requirements before echoing it back to clients.