import (
"net/http"
"github.com/zeromicro/go-zero/rest"
)
func add_router(method_type string, path string, handler http.HandlerFunc) rest.Route {
return rest.Route{
Method: method_type,
Path: "api/admin/" + path,
Handler: handler,
}
}
//路由定义
r = []rest.Route{
/*++++++++++++++++++++++++++++++会员部分++++++++++++++++++++++++*/
add_router(types.POST, "/members/list", response.WrapResponse(MembersList,login_chk.RouterCheckToken)),
}
return r
}
//response.WrapResponse定义
func WrapResponse(fn func(r *http.Request) (interface{}, error),checkTokenFunc func(r *http.Request) error) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
resp, err := fn(r)
if r.URL.Path != "/check/login" {
if checkTokenFunc != nil{
err := checkTokenFunc(r)
if err != nil {
handleErrorResponse(w,err)
return
}
}
}
if err == nil {
r := &Response{
Code: 0,
Msg: "success",
Data: resp,
}
httpx.WriteJson(w, http.StatusOK, r)
} else {
handleErrorResponse(w,err)
}
}
}
RouterCheckToken函数定义:
func (l *Login) RouterCheckToken(r *http.Request)(err error){
authorization := (*r).Header.Get(types.HEADER_AUTH)
exists,err := l.CheckToken(&authorization);
if err != nil{
return
}
if !exists{
//302跳转
return response.NewErrCodeMsg(200, "已过期,请通过refresh_token获取token或重新登录")
}
return
}
RouterCheckToken是校验是否登录的函数,如果过期返回错误消息,我想把他改造成过期了302跳转到登录页,应该怎么做
golang发起302重定向
- 写回答
- 好问题 0 提建议
- 关注问题
- 邀请回答
-
3条回答 默认 最新
关注让【宝码香车】来帮您解答,本回答参考DeepSeek编写,并整理提供。
如果答案能帮助您,请采纳,非常感谢!
.
每日一句正能量,让它带给您好心情:把日子过得有滋有味,就是对生活最好的回馈。
.在 Go 语言中实现 302 重定向,你需要在
RouterCheckToken函数中直接操作 HTTP 响应,而不是返回错误。以下是修改方案:方案一:修改 RouterCheckToken 函数
func (l *Login) RouterCheckToken(w http.ResponseWriter, r *http.Request) error { authorization := r.Header.Get(types.HEADER_AUTH) exists, err := l.CheckToken(&authorization) if err != nil { return err } if !exists { // 302 重定向到登录页 http.Redirect(w, r, "/login", http.StatusFound) return nil // 这里返回 nil 表示已经处理了响应 } return nil }方案二:修改 WrapResponse 函数签名和调用
由于
RouterCheckToken现在需要http.ResponseWriter参数,你需要修改WrapResponse函数:func WrapResponse(fn func(r *http.Request) (interface{}, error), checkTokenFunc func(w http.ResponseWriter, r *http.Request) error) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { // 先执行 token 检查 if r.URL.Path != "/check/login" { if checkTokenFunc != nil { err := checkTokenFunc(w, r) if err != nil { handleErrorResponse(w, err) return } // 如果 checkTokenFunc 执行了重定向,直接返回 if w.(interface{ Written() bool }).Written() { return } } } resp, err := fn(r) if err != nil { handleErrorResponse(w, err) return } r := &Response{ Code: 0, Msg: "success", Data: resp, } httpx.WriteJson(w, http.StatusOK, r) } }方案三:使用中间件模式(推荐)
更优雅的方式是使用中间件模式:
// 创建认证中间件 func AuthMiddleware(l *Login) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { authorization := r.Header.Get(types.HEADER_AUTH) exists, err := l.CheckToken(&authorization) if err != nil { handleErrorResponse(w, err) return } if !exists { // 302 重定向到登录页 http.Redirect(w, r, "/login", http.StatusFound) return } next.ServeHTTP(w, r) }) } } // 修改路由定义,使用中间件 func add_router(method_type string, path string, handler http.HandlerFunc, authRequired bool) rest.Route { var finalHandler http.HandlerFunc = handler if authRequired { finalHandler = func(w http.ResponseWriter, r *http.Request) { // 这里可以添加认证中间件 handler(w, r) } } return rest.Route{ Method: method_type, Path: "api/admin/" + path, Handler: finalHandler, } }方案四:修改现有代码的最简方式
如果你希望最小化修改现有代码,可以这样调整:
func (l *Login) RouterCheckToken(r *http.Request) error { authorization := r.Header.Get(types.HEADER_AUTH) exists, err := l.CheckToken(&authorization) if err != nil { return err } if !exists { // 返回特殊错误类型,在 WrapResponse 中处理重定向 return &RedirectError{URL: "/login"} } return nil } // 自定义重定向错误类型 type RedirectError struct { URL string } func (e *RedirectError) Error() string { return "need redirect to: " + e.URL } // 修改 WrapResponse 中的错误处理 func WrapResponse(fn func(r *http.Request) (interface{}, error), checkTokenFunc func(r *http.Request) error) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/check/login" { if checkTokenFunc != nil { err := checkTokenFunc(r) if err != nil { // 检查是否是重定向错误 if redirectErr, ok := err.(*RedirectError); ok { http.Redirect(w, r, redirectErr.URL, http.StatusFound) return } handleErrorResponse(w, err) return } } } resp, err := fn(r) if err != nil { handleErrorResponse(w, err) return } r := &Response{ Code: 0, Msg: "success", Data: resp, } httpx.WriteJson(w, http.StatusOK, r) } }推荐使用方案三的中间件模式,因为它更符合 Go 语言的惯用法,代码结构更清晰,也更容易维护和测试。
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报