HousewareHQ / backend-engineering-octernship

24 stars 13 forks source link

Unable to store cookies: http.Cookies are getting stored in postman but not in browser #4

Open thepranays opened 1 year ago

thepranays commented 1 year ago

On User 's successful login request ,I am saving tokens as http.cookies from the backend. When i make login request using postman the cookies are stored in postman's cookies but on the other hand if i make login request through my React.js client from browser they are not stored in browser's cookies section. i.e.(/devtools/application/cookies)

Code:

Storing cookie-

ctx.SetCookie("accesstoken", token, int(AppConstant.TOKEN_COOKIE_EXPIRY), "/", "localhost", false, true)
ctx.SetCookie("refreshtoken", refreshedToken, int(AppConstant.REFRESH_TOKEN_COOKIE_EXPIRY), "/", "localhost", false, true)

Login request from react.js client-

export async function AuthenticateUser  (username,password) {
        const res=await fetch(API_URL+API_LOGIN_ENDPOINT,{
        method:"POST",
        headers:{
            'Accept': 'application/json',   
            "Content-Type":"application/json"
        },

        mode:"cors",
        body:JSON.stringify({
            "username":username,
            "password":password,
        }),

    });
    return res.status===200

}

Frameworks used: Gin-Gonic(Backend) ,React.js(Frontend) Tested on Browsers:Firefox ,brave.

Although i have read and tried some threads on internet that latest browser ignores domain="localhost" and also domain containing less than 2 periods i.e. "api.app.localhost" is valid but "localhost" is not. One thing i could do is, get tokens from backend and then save them in cookies at client side and then further use them but that's not good practice as per many people. Then how can i achieve my goal of storing cookies in browser when domain is localhost ,In order to setup test environment for this assignment ?

thepranays commented 1 year ago

FIXED: Added self defined cors middleware - `func CORSMiddleware() gin.HandlerFunc { return func(c *gin.Context) { c.Writer.Header().Set("Access-Control-Allow-Origin", "http://localhost:3000") //ORIGIN:From where API calls will be made i.e.React.js client. c.Writer.Header().Set("Access-Control-Allow-Credentials", "true") //TO TRANSFER COOKIES c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With") c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, DELETE")

    if c.Request.Method == "OPTIONS" {
        c.AbortWithStatus(204)
        return
    }

    c.Next()
}

} ` And in request setted withCredentials:true in of axios config at client side

But now question i have is ,IS IT GOOD PRACTICE ?

Kdsingh333 commented 1 year ago

You already fixed it good see . for testing purpose you can add this c.Writer.Header().Set("Access-Control-Allow-Origin", "*"), it may be work.

thepranays commented 1 year ago

@Kdsingh333 I tried setting Access-Control-Allow-Origin to "",but then at client side it throws exception saying " The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '' when the request's credentials mode is 'include'."