gojwtjwt-go

How can I add JWT automatically after login?


I have a cruel doubt.

I'm running the code below:

package main

import (
    "net/http"
    "time"

    "github.com/dgrijalva/jwt-go"
    "github.com/labstack/echo"
    "github.com/labstack/echo/middleware"
)

func login(c echo.Context) error {
    username := c.FormValue("username")
    password := c.FormValue("password")

    if username == "jon" && password == "shhh!" {
        // Create token
        token := jwt.New(jwt.SigningMethodHS256)

        // Set claims
        claims := token.Claims.(jwt.MapClaims)
        claims["name"] = "Jon Snow"
        claims["admin"] = true
        claims["exp"] = time.Now().Add(time.Hour * 72).Unix()

        // Generate encoded token and send it as response.
        t, err := token.SignedString([]byte("secret"))
        if err != nil {
            return err
        }
        return c.JSON(http.StatusOK, map[string]string{
            "token": t,
        })
    }

    return echo.ErrUnauthorized
}

func accessible(c echo.Context) error {
    return c.String(http.StatusOK, "Accessible")
}

func restricted(c echo.Context) error {
    user := c.Get("user").(*jwt.Token)
    claims := user.Claims.(jwt.MapClaims)
    name := claims["name"].(string)
    return c.String(http.StatusOK, "Welcome "+name+"!")
}

func main() {
    e := echo.New()

    // Middleware
    e.Use(middleware.Logger())
    e.Use(middleware.Recover())

    // Login route
    e.POST("/login", login)

    // Unauthenticated route
    e.GET("/", accessible)

    // Restricted group
    r := e.Group("/restricted")
    r.Use(middleware.JWT([]byte("secret")))
    r.GET("", restricted)

    e.Logger.Fatal(e.Start(":1323"))
}

Font: https://echo.labstack.com/cookbook/jwt Playground: https://goplay.space/#-9_4N2jM5P

Everything is going well! But how do I add the token in the header, so when the user logs it to navigate between routes /restricted normally?

At the moment I can navigate the route /restricted if I add a header Authorization in POSTMAN for example.

But I want it to be automatic once the user logs in. Grateful!

Thanks guys.


Solution

  • When using JWT, the client typically have to specify the token itself. To make the token handling to be seamless for the client, you can send the token back as a cookie. You can configure echo's middleware to extract the token from a cookie:

    // ...
    r.Use(middleware.JWTWithConfig(middleware.JWTConfig{
        SigningKey: []byte("secret"),
        TokenLookup: "cookie:Authorization",
    }))
    

    For this to work you will need to send the token back as a cookie in your login handler:

    // ...
    c.SetCookie(http.Cookie{
        Name: "Authorization",
        Value: t,
        Path: "/root/path",
        Domain: "your.domain.com",
        HttpOnly: true,
    })
    return c.JSON(http.StatusOK, map[string]string{
        "token": t,
    })