英文:
Gorilla middleware authentication for specific routes not working
问题
我正在为一个API编写一个HTTP路由器,其中一些路由需要身份验证,而另一些则不需要。
我不想在每个路由上都要求身份验证,所以我将它们分开。
但是有一个问题:
POST /account <-- 这是一个账户注册端点,不需要身份验证
DELETE /account <-- 这需要身份验证才能删除当前账户
我不知道如何正确分离它们,而且我目前尝试的将中间件分别应用于这两个路由的方法失败了:
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()
// 不需要身份验证调用此路由
mainRouter.HandleFunc("/health", handlers.HealthGet).Methods("GET") // 获取API健康状态
// authRouter 应该是 mainRouter 的扩展(我认为)
mainRouter.Handle("/", authmiddlewares.Then(authRouter))
// 不需要身份验证调用此路由
mainRouter.HandleFunc("/account", handlers.AccountPost).Methods("POST") // 创建账户
// 需要身份验证调用此路由
authRouter.HandleFunc("/account", handlers.AccountDelete).Methods("DELETE") // 删除我的账户
// WebSocket 端点
authRouter.HandleFunc("/ws", handlers.UpgradeWs)
authRouter.HandleFunc("/ws/", handlers.UpgradeWs) // 如果我不添加这个,它就无法工作??
// 注册 mainRouter
http.Handle("/", defaultmiddlewares.Then(mainRouter))
}
对 GET /health 的调用是正常的:
但是对 DELETE /account 的调用失败,返回 404 Not Found:
(还有,在 Init() 函数的末尾,我注册了一个 WebSocket 端点,由于某种原因,如果我不注册这两个端点,它就无法连接?)
英文:
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?)
答案1
得分: 2
你初始化了两个路由器 mainRouter
和 authRouter
,但只启动了 mainRouter
。DELETE /account
绑定到了 authRouter
,但是它没有被启动和监听。这就是为什么会返回 404 错误的原因。
你可以编写自定义的中间件实现,使用 gorilla/mux
路由器的 gorilla/mux 中间件接口。示例代码如下:
func Init() {
log.Println("Initializing http routes...")
r := mux.NewRouter()
middleware := Middleware{
// 如果需要,可以注入任何依赖项
}
r.Use(middleware.MiddlewareFunc)
// 不需要身份验证调用此接口
r.HandleFunc("/health", handlers.HealthGet).Methods("GET") // 获取 API 健康状态
// authRouter 应该是 mainRouter 的扩展(我认为)
r.Handle("/", authmiddlewares.Then(authRouter))
// 此接口不需要身份验证
r.HandleFunc("/account", handlers.AccountPost).Methods("POST") // 创建账户
// 此接口需要身份验证
r.HandleFunc("/account", handlers.AccountDelete).Methods("DELETE") // 删除我的账户
http.ListenAndServe(":8080", r)
}
// Middleware 是你自定义的中间件实现
type Middleware struct {}
func (m Middleware) MiddlewareFunc(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// 在这里你可以检查请求方法和路径,并进行身份验证
// 例如:如果方法为 DELETE,路径为 /account,则进行身份验证
handler.ServeHTTP(w, r)
})
}
英文:
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)
})
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论