go-restful + JWT身份验证
问题描述:
我试图在用go-restful编写的非常简单的go服务中插入JWT身份验证。go-restful + JWT身份验证
的代码非常相似:
package main
import (
"github.com/emicklei/go-restful"
"log"
"net/http"
)
type User struct {
Id, Name string
}
type UserList struct {
Users []User
}
func getAllUsers(request *restful.Request, response *restful.Response) {
log.Printf("getAllUsers")
response.WriteEntity(UserList{[]User{{"42", "Gandalf"}, {"3.14", "Pi"}}})
}
func NewUserService() *restful.WebService {
ws := new(restful.WebService)
ws.
Path("/users").
Consumes(restful.MIME_XML, restful.MIME_JSON).
Produces(restful.MIME_JSON, restful.MIME_XML)
ws.Route(ws.GET("").To(getAllUsers))
return ws
}
func main() {
restful.Add(NewUserService())
log.Printf("start listening on localhost:8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
其中restful.Request
是围绕http.Request
的包装。
也就是说,可能使用Auth0 jwt middleware。
但作为golang新手,我在管道工程中有点迷失。我知道我必须使用Filter
功能像
ws.Filter(jwtAuthentication)
其中
func jwtAuthentication(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) {
// Jwt Magic goes here \o
chain.ProcessFilter(req, resp)
}
但我不弄清楚如何以及在何处,我应该实例化的智威汤逊中间件。
答
下面是使用auth0/go-jwt-middleware过滤器实现的示例。在现实生活中,您可能希望避免每次创建新的jwtMiddleware
实例。
func jwtAuthentication(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) {
jwtMiddleware := jwtmiddleware.New(jwtmiddleware.Options{
ValidationKeyGetter: func(token *jwt.Token) (interface{}, error) {
return []byte("My Secret"), nil
},
SigningMethod: jwt.SigningMethodHS256,
})
if err := jwtMiddleware.CheckJWT(resp.ResponseWriter, req.Request); err != nil {
logger.Errorf("Authentication error: %v", err)
}
chain.ProcessFilter(req, resp)
}
过滤器后,将解析的令牌将在上下文(auth0/go-jwt-middleware使用gorilla/context)。默认的上下文关键是user
。
注意:当设置了JWTMiddleware.SigningMethod
时,中间件会验证令牌是否使用特定的签名算法进行签名。
如果签名方法不固定,则可以使用ValidationKeyGetter
回调来实施其他检查。
重要的是要避免描述的安全问题here。