golang http middleware实现
在登录后,可以使用中间件在处理业务逻辑前,先进行验证.
func AuthOn(hFunc func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Printf("AuthOn %v, token %v\n", r.URL.Path, r.Header)
hFunc(w, r)
})
}
// in func main
http.HandleFunc("/itemlist", AuthOn(getItemHandler))
关联jwt验证middleware, 携带的token
只能放到header中; 如果放到body中,会影响正常的handler代码读取body中的字段.
func VerifyJWT(tokenString string) (jwt.MapClaims, error) {
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
// Don't forget to validate the alg is what you expect:
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
}
// hmacSampleSecret is a []byte containing your secret, e.g. []byte("my_secret_key")
return hmacSampleSecret, nil
})
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
log.Println(claims["openid"], claims["exp"])
return claims, nil
}
log.Println(err)
return nil, err
}
func AuthOn(hFunc func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
token := r.Header.Get("token")
log.Printf("AuthOn %v %v\n", r.URL.Path, token)
if c, err := VerifyJWT(token); err == nil {
da := c["devarea"]
r.Header.Add("devarea", da.(string))
hFunc(w, r)
} else {
log.Printf("AuthOn failed", err)
}
})
}