首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GO和Go-Gin的JWT令牌验证问题

GO和Go-Gin的JWT令牌验证问题
EN

Stack Overflow用户
提问于 2022-09-30 12:57:24
回答 1查看 339关注 0票数 1

我正在使用Youtube教程(GIN + GO + JWT)。我已经实现了令牌验证中间件。它运行良好,JWT配置的cookie与请求一起传递。如果没有令牌,它会阻塞带有401错误的请求,但也会导致500服务器错误。已经通过了JWT 文档,但无法解决这个问题。

中间件:

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

错误:

代码语言:javascript
复制
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/gin@v1.8.1/context.go:173 (0x166e361)
        (*Context).Next: c.handlers[c.index](c)
/Users/genex/golang/pkg/mod/github.com/gin-gonic/gin@v1.8.1/recovery.go:101 (0x166e34c)
        CustomRecoveryWithWriter.func1: c.Next()
/Users/genex/golang/pkg/mod/github.com/gin-gonic/gin@v1.8.1/context.go:173 (0x166d466)
        (*Context).Next: c.handlers[c.index](c)
/Users/genex/golang/pkg/mod/github.com/gin-gonic/gin@v1.8.1/logger.go:240 (0x166d449)
        LoggerWithConfig.func1: c.Next()
/Users/genex/golang/pkg/mod/github.com/gin-gonic/gin@v1.8.1/context.go:173 (0x166c530)
        (*Context).Next: c.handlers[c.index](c)
/Users/genex/golang/pkg/mod/github.com/gin-gonic/gin@v1.8.1/gin.go:616 (0x166c198)
        (*Engine).handleHTTPRequest: c.Next()
/Users/genex/golang/pkg/mod/github.com/gin-gonic/gin@v1.8.1/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"
EN

回答 1

Stack Overflow用户

发布于 2022-09-30 13:22:56

错误是第37行中的invalid memory address or nil pointer dereference

代码语言:javascript
复制
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {

那是因为token在这里是nil。(您可以写到,这是不带令牌的。)

上面写着在文档

AbortWithStatus调用Abort()…中止阻止调用挂起的处理程序。请注意,这将不会停止当前处理程序的。(由我移情)

因此,您需要在调用return之后使用c.AbortWithStatus(http.StatusUnauthorized)语句,以便在发生错误时退出函数。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73909156

复制
相关文章

相似问题

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