maciek_pl1234
maciek_pl1234

Reputation: 29

GetSession in gin-contrib/sessions returning nil of token

So, i just created a backend setting session and getting session for my app. I would like to access via endpoint getting session i did that, but always session value returning nil even if i had set token inside session via SetSession function on userLogin.

I am using GIN framework + Gin/sessions on backend and Next.js on frontend.

I just tried checking session inside SetSession and there everything working fine, but when request come in from frontend hook, session returning nil which giving me message "Session expired" and error: true.

It should return me token and next check token via function and and the end return for the frontend token to let user enter /dashboard page.

I don't have any more idea why this happen and what can i do with that.

Code:

func GetSession(c *gin.Context) {
    session := sessions.Default(c)
    if value := session.Get("token"); value == nil {
        c.JSON(http.StatusUnauthorized, gin.H{
            "message": "No token present/Session expired",
            "error":   true,
        })
        return
    } else {
        token := value.(string)
        tokenCheck, _ := lib.CheckSecureToken(token)
        if tokenCheck == false {
            c.JSON(http.StatusUnauthorized, gin.H{
                "message": "Invalid token",
                "error":   true,
            })
            return
        }
        c.JSON(http.StatusOK, gin.H{
            "message": "Token present",
            "token":   value.(string),
            "error":   false,
        })
    }
    return
}
func SetSession(c *gin.Context, token string, status int) {
    session := sessions.Default(c)
    session.Set("token", token)
    err := session.Save()
    if err != nil {
        c.JSON(500, gin.H{
            "message": "Error saving session, user not logged in",
            "error":   true,
            "status":  500,
        })
    }
    c.JSON(status, gin.H{
        "message": "User logged in successfully",
        "token":   token,
        "error":   false,
        "status":  200,
    })
}
func SetupRouter() *gin.Engine {
    r := gin.Default()
    config := cors.DefaultConfig()
    store := cookie.NewStore([]byte("")) //Secret is set
    store.Options(sessions.Options{
        MaxAge: 60 * 60 * 24,
    })
    r.Use(sessions.Sessions("usersession", store))
    config.AllowOrigins = []string{"http://localhost:3000"}
    r.Use(cors.New(config))
    r.GET("/", home)

    //Auth routes
    authGroup := r.Group("/api/v1/auth")
    //authGroup.POST("/logout", logoutUser)
    //authGroup.POST("/refresh", refreshUser)
    //authGroup.POST("/forgot", forgotPassword)
    //authGroup.POST("/reset", resetPassword)
    authGroup.POST("/login", loginUser)
    authGroup.POST("/signup", createUser)
    authGroup.GET("/check", handler.GetSession)
func loginUser(c *gin.Context) {
    var user database.User
    err := c.BindJSON(&user)
    if err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error(), "message": "User not found"})
        return
    }
    db, errS := database.LoginUser(&user)
    if errS != nil {
        c.JSON(http.StatusBadRequest, gin.H{"type": "Authentication Error", "message": "Invalid email or password", "status": "400"})
        return
    }
    token := lib.GenerateSecureToken(user.Email)
    if db.IsAdmin {
        adminToken := lib.GenerateAdminSecureToken(user.Email)
        cookieAdmin := adminToken
        handler.SetAdminSession(c, cookieAdmin, 200)
    }
    handler.SetSession(c, token, 200)
}```

Upvotes: 1

Views: 613

Answers (1)

Runpu Yue
Runpu Yue

Reputation: 1

I've had a similar situation where the first request on the frontend has a session set on the backend, but the next request can't get it. The reason is that axios I used in frontend does not have slack cookies configured.

// global config
axios.defaults.withCredentials = true


// single request config
axios.get('/test', {
  withCredentials: true
})

Also, don't forget to configure cross-domain access in gin:

func Cors() gin.HandlerFunc {
return func(c *gin.Context) {
        method := c.Request.Method
        origin := c.GetHeader("Origin")
        c.Header("Access-Control-Allow-Origin", origin)                                                                                                                          // 注意这一行,不能配置为通配符“*”号
        c.Header("Access-Control-Allow-Credentials", "true")                                                                                                                     // 注意这一行,必须设定为 true
        c.Header("Access-Control-Allow-Headers", "Access-Control-Allow-Headers,Cookie, Origin, X-Requested-With, Content-Type, Accept, Authorization, Token, Timestamp, UserId") // 我们自定义的header字段都需要在这里声明
        c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS,DELETE,PUT")
        c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type,cache-control")

        
        if method == "OPTIONS" {
            //c.AbortWithStatus(http.StatusNoContent)
            c.AbortWithStatus(http.StatusOK)
        }
        
        c.Next()
    }
}

router := gin.New()
router.Use(middleware.Cors())

Upvotes: 0

Related Questions