在登录后如何自动添加JWT?

huangapple go评论102阅读模式
英文:

How can I add JWT automatically after login?

问题

我有一个疑问。

我正在运行下面的代码:

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!" {
		// 创建令牌
		token := jwt.New(jwt.SigningMethodHS256)

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

		// 生成编码的令牌并将其作为响应发送
		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()

	// 中间件
	e.Use(middleware.Logger())
	e.Use(middleware.Recover())

	// 登录路由
	e.POST("/login", login)

	// 未经身份验证的路由
	e.GET("/", accessible)

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

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

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

一切都进行得很顺利!但是,当用户登录后,我如何将令牌添加到标头中,以便能够正常在路由**/restricted**之间导航?

目前,如果我在POSTMAN中添加一个名为Authorization的标头,我可以访问路由**/restricted**。

但是我希望一旦用户登录,这个过程可以自动完成。谢谢!

英文:

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.

答案1

得分: 2

当使用JWT时,客户端通常需要指定令牌本身。为了使客户端的令牌处理更加无缝,您可以将令牌作为cookie发送回去。您可以配置echo的中间件来从cookie中提取令牌:

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

为了使其工作,您需要在登录处理程序中将令牌作为cookie发送回去:

// ...
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,
})

英文:

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

答案2

得分: 0

你可以在/accesible路由上添加中间件,没有问题,此时该路由与登录一样是公开的。

令牌头始终从发出请求的位置发送,它位于名为Authorization的头部中,并且必须指示令牌的类型和令牌本身,除了可以包含额外的信息。

编辑:

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

你必须为此创建一个中间件。

祝你好运。

英文:

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

huangapple
  • 本文由 发表于 2017年7月14日 00:02:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/45085866.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定