How to use external endpoint to set jwt cookies in sveltekit

Viewed 71

I wanted to set jwt cookie in a Sveltekit application from a Golang API. The following code runs successfully but no cookie is set in the browser. Is it impossible to set jwt cookie from an external API?
My most of the work is done in a external API that's why i wanted to do the authentication from that same API.

In Sveltekit code,

async function OnSubmit() {
        //test
        let res = await fetch('http://localhost:50000/login', {
            credentials: 'same-origin',
            method: 'POST',
            mode: 'cors',
            body: JSON.stringify({
                Username: 'raka',
                Password: 'password1'
            })
        });
        console.log(' ~ file: index@blank.svelte ~ line 45 ~ OnSubmit ~ res', res);
        if (res.ok) {
            
            console.log(' ~ file: index.svelte ~ line 49 ~ OnSubmit ~ value : ', 200);
            
        }

}

In Golang API,

func main() {
    http.HandleFunc("/login", handler.Login)
    http.HandleFunc("/home", handler.Home)
    http.HandleFunc("/", handler.Home2)
    http.HandleFunc("/refresh", handler.Refresh)

    fmt.Println("listening in port 50000")
    log.Fatal(http.ListenAndServe(":50000", nil))

}

func Login(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Access-Control-Allow-Origin", "*")

    w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
    fmt.Println("Login is hit ...")
    var credentials Credentials

    err := json.NewDecoder(r.Body).Decode(&credentials)

    if err != nil {
        w.WriteHeader(http.StatusBadRequest)
        return
    }
    expectedPassword, ok := Users[credentials.Username]

    if !ok || expectedPassword != credentials.Password {
        w.WriteHeader(http.StatusUnauthorized)
        return
    }

    expirationTime := time.Now().Add(time.Minute * 5)

    claims := &Claims{
        Username: credentials.Username,
        StandardClaims: jwt.StandardClaims{
            ExpiresAt: expirationTime.Unix(),
        },
    }

    token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

    tokenString, err := token.SignedString(jwtKey)

    if err != nil {
        w.WriteHeader(http.StatusInternalServerError)
        return
    }

    http.SetCookie(w, &http.Cookie{
        Name:    "token",
        Value:   tokenString,
        Expires: expirationTime,
    })

}
1 Answers

use hooks, something like below should work.

in hooks.js:

    import {serialize } from 'cookie'; //pnpm install cookie
    
    export async function handle({ event, resolve }) {
      if (event.url.pathname.startsWith('/login')) {
        let res = await fetch('http://localhost:50000/login', {
                credentials: 'same-origin',
                method: 'POST',
                mode: 'cors',
                body: JSON.stringify({
                    Username: 'raka',
                    Password: 'password1'
                })
            });
    
        if (res.ok) {
         let tokenCookie = serialize('jwt', jwt, {
                    path: '/',
                    httpOnly: true,
                    sameSite: 'strict',
                    secure: true,
                    maxAge: 60 * 60, // 1hr
                })
    
          let response = new Response(JSON.stringify({}));
          response.headers.set('Set-Cookie', tokenCookie);
          return response;
        }
    }
}
Related