首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >go-restful + JWT身份验证

go-restful + JWT身份验证
EN

Stack Overflow用户
提问于 2016-09-30 04:16:52
回答 2查看 1.8K关注 0票数 0

我正在尝试将JWT身份验证插入到一个用go-restful编写的非常简单的go服务中。

代码非常类似于:

代码语言:javascript
复制
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.Requesthttp.Request的包装器。

话虽如此,使用Auth0 jwt middleware也是可能的。

但作为一个戈朗新手,我有点迷失在管道的过程中。我知道我必须使用一个Filter函数,比如

代码语言:javascript
复制
ws.Filter(jwtAuthentication)

哪里

代码语言:javascript
复制
func jwtAuthentication(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) {
    // Jwt Magic goes here \o
    chain.ProcessFilter(req, resp)
}

但是我不知道应该如何以及在哪里实例化JWT中间件。

EN

回答 2

Stack Overflow用户

发布于 2017-03-22 23:39:08

下面是使用auth0/go-jwt-middleware实现过滤器的示例。在现实生活中,您可能希望避免每次都创建新的jwtMiddleware实例。

代码语言:javascript
复制
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描述的安全问题。

票数 2
EN

Stack Overflow用户

发布于 2018-12-08 01:42:53

以下是生成令牌登录API和检查身份验证的JWT身份验证筛选器的示例

代码语言:javascript
复制
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)
}

然后应用过滤器

代码语言:javascript
复制
ws.Filter(JwtAuthentication)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39779243

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档