appleboy / gin-jwt

JWT Middleware for Gin framework
MIT License
2.73k stars 382 forks source link

invalid memory address or nil pointer dereference on LoginHandler #304

Closed tomriddle1234 closed 1 year ago

tomriddle1234 commented 1 year ago

Here's the error message, seems it is from system? v2.8.0, gin 1.8.1, go 1.18.1, ubuntu 20.04 64 virtual machine.

2022/09/27 19:02:54 [Recovery] 2022/09/27 - 19:02:54 panic recovered:
POST /u/login HTTP/1.1
Host: 127.0.0.1:42647
Accept-Encoding: gzip
Content-Length: 63
Content-Type: application/json; charset=utf-8
User-Agent: Go-http-client/1.1

runtime error: invalid memory address or nil pointer dereference
/snap/go/9952/src/runtime/panic.go:220 (0x44e67c)
    panicmem: panic(memoryError)
/snap/go/9952/src/runtime/signal_unix.go:818 (0x44e64c)
    sigpanic: panicmem()
/home/tom/go/pkg/mod/github.com/appleboy/gin-jwt/v2@v2.8.0/auth_jwt.go:526 (0x961f47)
    (*GinJWTMiddleware).LoginHandler: mw.LoginResponse(c, http.StatusOK, tokenString, expire)
/home/tom/go/pkg/mod/github.com/gin-gonic/gin@v1.8.1/context.go:173 (0x952226)
    (*Context).Next: c.handlers[c.index](c)
/home/tom/go/pkg/mod/github.com/gin-gonic/gin@v1.8.1/logger.go:240 (0x952209)
    LoggerWithConfig.func1: c.Next()
/home/tom/go/pkg/mod/github.com/gin-gonic/gin@v1.8.1/context.go:173 (0x953141)
    (*Context).Next: c.handlers[c.index](c)
/home/tom/go/pkg/mod/github.com/gin-gonic/gin@v1.8.1/recovery.go:101 (0x95312c)
    CustomRecoveryWithWriter.func1: c.Next()
/home/tom/go/pkg/mod/github.com/gin-gonic/gin@v1.8.1/context.go:173 (0x952226)
    (*Context).Next: c.handlers[c.index](c)
/home/tom/go/pkg/mod/github.com/gin-gonic/gin@v1.8.1/logger.go:240 (0x952209)
    LoggerWithConfig.func1: c.Next()
/home/tom/go/pkg/mod/github.com/gin-gonic/gin@v1.8.1/context.go:173 (0x9512f0)
    (*Context).Next: c.handlers[c.index](c)
/home/tom/go/pkg/mod/github.com/gin-gonic/gin@v1.8.1/gin.go:616 (0x950f58)
    (*Engine).handleHTTPRequest: c.Next()
/home/tom/go/pkg/mod/github.com/gin-gonic/gin@v1.8.1/gin.go:572 (0x950a9c)
    (*Engine).ServeHTTP: engine.handleHTTPRequest(c)
/snap/go/9952/src/net/http/server.go:2916 (0x76385a)
    serverHandler.ServeHTTP: handler.ServeHTTP(rw, req)
/snap/go/9952/src/net/http/server.go:1966 (0x75e856)
    (*conn).serve: serverHandler{c.server}.ServeHTTP(w, w.req)
/snap/go/9952/src/runtime/asm_amd64.s:1571 (0x46b6c0)
    goexit: BYTE    $0x90   // NOP

[GIN] 2022/09/27 - 19:02:54 | 500 |  101.201174ms |       127.0.0.1 | POST     "/u/login"
2022/09/27 19:02:54 
2022/09/27 19:02:54 Login test with valid user response status Error!

The problem seems for my own code it is from the Authenticator, like so, followed the example

func authJWT(c *gin.Context) (interface{}, error) {
    //the login info just contain username and password

    var loginU user
    if err := c.ShouldBindJSON(&loginU); err != nil {
        log.Println(err.Error() + " authJWT() cannot parse input loginU variable")

        return "", jwt.ErrMissingLoginValues
    }

    if isUserValid(loginU.Username, loginU.Password) {
        log.Println("authJWT() is called! 3 " + loginU.Username)

               // PROBLEM HERE
        return &user{
            Username: loginU.Username,
        }, nil
    }

    return nil, jwt.ErrFailedAuthentication
}

From the error message, error from the LoginHander, like so

/home/tom/src/cadip/adip-backend/gopath/pkg/mod/github.com/appleboy/gin-jwt/v2@v2.8.0/auth_jwt.go:526 (0x961f47)
        (*GinJWTMiddleware).LoginHandler: mw.LoginResponse(c, http.StatusOK, tokenString, expire)

        ...
    if mw.SendCookie {
        expireCookie := mw.TimeFunc().Add(mw.CookieMaxAge)
        maxage := int(expireCookie.Unix() - mw.TimeFunc().Unix())

        if mw.CookieSameSite != 0 {
            c.SetSameSite(mw.CookieSameSite)
        }

        c.SetCookie(
            mw.CookieName,
            tokenString,
            maxage,
            "/",
            mw.CookieDomain,
            mw.SecureCookie,
            mw.CookieHTTPOnly,
        )
    }
        //PROBLEM HERE, why??
    mw.LoginResponse(c, http.StatusOK, tokenString, expire)
}
tomriddle1234 commented 1 year ago

Solved this issue, I was using my old code that there's no initiation for gin-jwt jwt.GinJWTMiddleware, after added

    authNormalUserMiddleware, err := jwt.New(&jwt.GinJWTMiddleware{
        ...
    })

    if err != nil {
        log.Fatal("JWT Error:" + err.Error())
    }

    // When you use jwt.New(), the function is already automatically called for checking,
    // which means you don't need to call it again.
    errInit := authNormalUserMiddleware.MiddlewareInit()

    if errInit != nil {
        log.Fatal("authNormalUserMiddleware.MiddlewareInit() Error:" + errInit.Error())
    }

The issue is gone.