Reputation: 57
Im writing a http router for a API and some routes require authentication while some dont.
I dont want to ask for authentication on every route, so I split them up.
But theres a problem:
POST /account <-- This is a account registration endpoint, and does not require authentication
DELETE /account <-- This does require authentication to delete the current account
I have no idea how to seperate these properly, also my current attempt at making the middleware different for the two is failing:
package httpServer
import (
"log"
"net/http"
"httpServer/handlers"
"httpServer/middlewares"
"github.com/gorilla/mux"
"github.com/justinas/alice"
)
func Init() {
log.Println("Initializing http routes...")
defaultmiddlewares := alice.New(middlewares.Logger, middlewares.Recover)
authmiddlewares := alice.New(middlewares.Authenticator)
var mainRouter = mux.NewRouter()
var authRouter = mux.NewRouter()
// No auth required to call this
mainRouter.HandleFunc("/health", handlers.HealthGet).Methods("GET") // Get API health
// authrouter should be a extension of main router (i think)
mainRouter.Handle("/", authmiddlewares.Then(authRouter))
// Authentication is not required for this
mainRouter.HandleFunc("/account", handlers.AccountPost).Methods("POST") // Create an account
// Authentication is required for this
authRouter.HandleFunc("/account", handlers.AccountDelete).Methods("DELETE") // Delete my account
// WebSocket endpoint:
authRouter.HandleFunc("/ws", handlers.UpgradeWs)
authRouter.HandleFunc("/ws/", handlers.UpgradeWs) // If i dont add this it doesnt work??
// Register mainRouter
http.Handle("/", defaultmiddlewares.Then(mainRouter))
}
Calls to GET /health are just fine:
But calls to DELETE /account are failing with a 404 Not Found:
(Also near the end of the Init() function i register a websocket endpoint, for some reason if i dont register both those endpoints it fails to connect?)
Upvotes: 0
Views: 1582
Reputation: 4095
You initialised two routers mainRouter
and authRouter
and only start mainRouter
. DELETE /account
is bound to authRouter
. That is not started and listening. That is why 404 coming.
And you can write custom middleware implementations to gorilla/mux Middleware interface and use with gorilla/mux
router. Example code is like below
func Init() {
log.Println("Initializing http routes...")
r := mux.NewRouter()
middleware := Middleware{
// inject any dependency if you need
}
r.Use(middleware.MiddlewareFunc)
// No auth required to call this
r.HandleFunc("/health", handlers.HealthGet).Methods("GET") // Get API health
// authrouter should be a extension of main router (i think)
r.Handle("/", authmiddlewares.Then(authRouter))
// Authentication is not required for this
r.HandleFunc("/account", handlers.AccountPost).Methods("POST") // Create an account
// Authentication is required for this
r.HandleFunc("/account", handlers.AccountDelete).Methods("DELETE") // Delete my account
http.ListenAndServe(":8080", r)
}
// Middleware your custom middleware implementation
type Middleware struct {}
func (m Middleware) MiddlewareFunc(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// you can check request method and paths and you can do authentications here
//eg := method = DELETE and path = /account, do authentication
handler.ServeHTTP(w, r)
})
}
Upvotes: 2