How can I add JWT automatically after login?

1.1k Views Asked by At

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.

2

There are 2 best solutions below

0
On BEST ANSWER

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,
})
0
On

you could add middleware to /accesible route, no problem, in this moment that route is public same the login.

The token header is always sent from where the request is made, it goes in a header called Authorization and must indicate the type of token and the token, in addition to being able to contain extra information.

EDIT:

r := e.Group("/restricted") -> r := e.Group("/restricted", middlewareAuth)

You must create a middleware for this.

Good luck