登录
首页 >  Golang >  Go问答

解决 Go-Gin 中 JWT 令牌验证的问题

来源:stackoverflow

时间:2024-02-14 08:27:26 105浏览 收藏

对于一个Golang开发者来说,牢固扎实的基础是十分重要的,golang学习网就来带大家一点点的掌握基础知识点。今天本篇文章带大家了解《解决 Go-Gin 中 JWT 令牌验证的问题》,主要介绍了,希望对大家的知识积累有所帮助,快点收藏起来吧,否则需要时就找不到了!

问题内容

我正在遵循 youtube 教程来使用 (gin + go + jwt)。我已经实现了令牌验证中间件。它工作正常,jwt 配置的 cookie 随请求一起传递。如果没有令牌,它会阻止请求并出现 401 错误,但也会导致 500 服务器错误。已查看 jwt 文档但无法解决问题。

中间件:

package middleware

import (
    "fmt"
    "net/http"
    "os"
    "time"

    "github.com/fahad-md-kamal/go-jwt/initializers"
    "github.com/fahad-md-kamal/go-jwt/models"
    "github.com/gin-gonic/gin"
    "github.com/golang-jwt/jwt/v4"
)

func requrieauth(c *gin.context) {
    // get the cookie off req
    tokenstring, err := c.cookie("authorization")
    
    if err != nil  {
        c.abortwithstatus(http.statusunauthorized)
    }

    // decode/validate it
    token, err := jwt.parse(tokenstring, func(token *jwt.token) (interface{}, error) {
        if _, ok := token.method.(*jwt.signingmethodhmac); !ok {
            return nil, fmt.errorf("unexpected signing method: %v", token.header["alg"])
        }
    
        return []byte(os.getenv("secret")), nil
    })

    if token == nil {
        // fmt.println(token.valid)
        c.abortwithstatus(http.statusunauthorized)
    }

    if claims, ok := token.claims.(jwt.mapclaims); ok{

        if float64(time.now().unix()) > claims["exp"].(float64){
            c.abortwithstatus(http.statusunauthorized)
        }
        // find the user with token sub
        var user models.user
        initializers.db.first(&user,claims["sub"])
        
        if user.id == 0 {
            c.abortwithstatus(http.statusunauthorized)
        }

        // attach to req
        c.set("user", user)

        // continue
        c.next()

        } else {
        c.abortwithstatus(http.statusunauthorized)
    }
}

错误:

2022/09/30 18:50:47 [Recovery] 2022/09/30 - 18:50:47 panic recovered:
GET /validate HTTP/1.1
Host: localhost:8000
Accept: */*
Accept-Encoding: gzip, deflate, br
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 102
Content-Type: application/json
Postman-Token: 9950b831-aa25-4ba3-a1eb-17c0fd8db5b4
User-Agent: PostmanRuntime/7.29.2


runtime error: invalid memory address or nil pointer dereference
/usr/local/opt/go/libexec/src/runtime/panic.go:260 (0x104c475)
        panicmem: panic(memoryError)
/usr/local/opt/go/libexec/src/runtime/signal_unix.go:835 (0x104c445)
        sigpanic: panicmem()
/Users/genex/Desktop/golang/jwt/middleware/requireAuth.go:37 (0x168016a)
        RequrieAuth: if claims, ok := token.Claims.(jwt.MapClaims); ok{
/Users/genex/golang/pkg/mod/github.com/gin-gonic/[email protected]/context.go:173 (0x166e361)
        (*Context).Next: c.handlers[c.index](c)
/Users/genex/golang/pkg/mod/github.com/gin-gonic/[email protected]/recovery.go:101 (0x166e34c)
        CustomRecoveryWithWriter.func1: c.Next()
/Users/genex/golang/pkg/mod/github.com/gin-gonic/[email protected]/context.go:173 (0x166d466)
        (*Context).Next: c.handlers[c.index](c)
/Users/genex/golang/pkg/mod/github.com/gin-gonic/[email protected]/logger.go:240 (0x166d449)
        LoggerWithConfig.func1: c.Next()
/Users/genex/golang/pkg/mod/github.com/gin-gonic/[email protected]/context.go:173 (0x166c530)
        (*Context).Next: c.handlers[c.index](c)
/Users/genex/golang/pkg/mod/github.com/gin-gonic/[email protected]/gin.go:616 (0x166c198)
        (*Engine).handleHTTPRequest: c.Next()
/Users/genex/golang/pkg/mod/github.com/gin-gonic/[email protected]/gin.go:572 (0x166bcdc)
        (*Engine).ServeHTTP: engine.handleHTTPRequest(c)
/usr/local/opt/go/libexec/src/net/http/server.go:2947 (0x12a7dab)
        serverHandler.ServeHTTP: handler.ServeHTTP(rw, req)
/usr/local/opt/go/libexec/src/net/http/server.go:1991 (0x12a2fc6)
        (*conn).serve: serverHandler{c.server}.ServeHTTP(w, w.req)
/usr/local/opt/go/libexec/src/runtime/asm_amd64.s:1594 (0x1067740)
        goexit: BYTE    $0x90   // NOP

[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 401 with 500
[GIN] 2022/09/30 - 18:50:47 | 500 |    6.815587ms |             ::1 | GET      "/validate"


正确答案


错误是第 37 行中的 in 无效内存地址或 nil 指针取消引用

if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {

那是因为 token 在这里是 nil 。 (您写道,没有令牌就会发生这种情况。)

docs 中写道:

abortwithstatus 调用 abort()... 中止可防止调用挂起的处理程序。请注意,这将不会停止当前处理程序。(我强调)

因此,在调用 c.abortwithstatus(http.statusunauthorized) 后,您需要 return 语句,以便在出现错误时退出函数。

今天关于《解决 Go-Gin 中 JWT 令牌验证的问题》的内容就介绍到这里了,是不是学起来一目了然!想要了解更多关于的内容请关注golang学习网公众号!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>