Rest 休息一下+;JWT认证
我试图在一个非常简单的go服务中插入JWT身份验证 代码非常类似于:Rest 休息一下+;JWT认证,rest,go,jwt,jwt-go,go-restful,Rest,Go,Jwt,Jwt Go,Go Restful,我试图在一个非常简单的go服务中插入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,
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
的包装器
也就是说,可能会使用
但是作为一个golang的新手,我对管道工程有点迷茫。我知道我必须使用过滤器函数,如
ws.Filter(jwtAuthentication)
在哪里
但是我不知道如何以及在何处实例化JWT中间件。这里是使用的过滤器实现示例。在现实生活中,您可能希望避免每次都创建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)
}
过滤器之后,解析的令牌将位于上下文中(uses)。默认上下文键是user
注意:当设置了JWTMiddleware.SigningMethod
时,中间件将验证令牌是否使用特定的签名算法签名
如果签名方法不是常量,则可以使用ValidationKeyGetter
回调来实现额外的检查
重要的是要避免所描述的安全问题。以下是使用的过滤器实现示例。在现实生活中,您可能希望避免每次都创建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)
}
过滤器之后,解析的令牌将位于上下文中(uses)。默认上下文键是user
注意:当设置了JWTMiddleware.SigningMethod
时,中间件将验证令牌是否使用特定的签名算法签名
如果签名方法不是常量,则可以使用ValidationKeyGetter
回调来实现额外的检查
重要的是要避免所描述的安全问题。这里是用于生成令牌的登录API和用于检查身份验证的JWT身份验证过滤器的示例
import (
"os"
"strings"
"github.com/dgrijalva/jwt-go"
"golang.org/x/crypto/bcrypt"
)
type Token struct {
UserId uint
Username string
jwt.StandardClaims
}
type Account struct {
ID uint
Email string
Password string
Token string
}
func Login(request *restful.Request, response *restful.Response) {
account := &Account{ID: 1, Email: "test@email.com" }
// TODO - account should be pulled from database
tk := &Token{ UserId: account.ID }
token := jwt.NewWithClaims(jwt.GetSigningMethod("HS256"), tk)
tokenString, _ := token.SignedString([]byte("JWT-SECRET-GOES-RIGHT-HERE"))
account.Token = tokenString
account.Password = ''
response.WriteEntity(account)
}
func JwtAuthentication(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) {
tokenHeader := req.Request.HeaderParameter("Authorization")
if tokenHeader == "" {
resp.WriteErrorString(http.StatusForbidden, "Not Authorized")
return
}
splitted := strings.Split(tokenHeader, " ")
if len(splitted) != 2 {
resp.WriteErrorString(http.StatusForbidden, "Not Authorized")
return
}
tokenPart := splitted[1]
tk := &Token{}
token, err := jwt.ParseWithClaims(tokenPart, tk, func(token *jwt.Token) (interface{}, error) {
return []byte("JWT-SECRET-GOES-RIGHT-HERE"), nil
})
if err != nil { //Malformed token, returns with http code 403 as usual
resp.WriteErrorString(http.StatusForbidden, "Not Authorized")
return
}
if !token.Valid { //Token is invalid, maybe not signed on this server
resp.WriteErrorString(http.StatusForbidden, "Not Authorized")
return
}
chain.ProcessFilter(req, resp)
}
然后应用过滤器
ws.Filter(JwtAuthentication)
下面是用于生成令牌的登录API和用于检查身份验证的JWT身份验证过滤器的示例
import (
"os"
"strings"
"github.com/dgrijalva/jwt-go"
"golang.org/x/crypto/bcrypt"
)
type Token struct {
UserId uint
Username string
jwt.StandardClaims
}
type Account struct {
ID uint
Email string
Password string
Token string
}
func Login(request *restful.Request, response *restful.Response) {
account := &Account{ID: 1, Email: "test@email.com" }
// TODO - account should be pulled from database
tk := &Token{ UserId: account.ID }
token := jwt.NewWithClaims(jwt.GetSigningMethod("HS256"), tk)
tokenString, _ := token.SignedString([]byte("JWT-SECRET-GOES-RIGHT-HERE"))
account.Token = tokenString
account.Password = ''
response.WriteEntity(account)
}
func JwtAuthentication(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) {
tokenHeader := req.Request.HeaderParameter("Authorization")
if tokenHeader == "" {
resp.WriteErrorString(http.StatusForbidden, "Not Authorized")
return
}
splitted := strings.Split(tokenHeader, " ")
if len(splitted) != 2 {
resp.WriteErrorString(http.StatusForbidden, "Not Authorized")
return
}
tokenPart := splitted[1]
tk := &Token{}
token, err := jwt.ParseWithClaims(tokenPart, tk, func(token *jwt.Token) (interface{}, error) {
return []byte("JWT-SECRET-GOES-RIGHT-HERE"), nil
})
if err != nil { //Malformed token, returns with http code 403 as usual
resp.WriteErrorString(http.StatusForbidden, "Not Authorized")
return
}
if !token.Valid { //Token is invalid, maybe not signed on this server
resp.WriteErrorString(http.StatusForbidden, "Not Authorized")
return
}
chain.ProcessFilter(req, resp)
}
然后应用过滤器
ws.Filter(JwtAuthentication)