1. JSON Web令牌

如今有很多将身份验证内置到API中的方法 -JSON Web令牌只是其中之一。JSON Web令牌(JWT)作为令牌系统而不是在每次请求时都发送用户名和密码,因此比其他方法(如基本身份验证)具有固有的优势。要了解更多信息,请直接进入jwt.io上的介绍,然后再直接学习。

以下是JWT的实际应用示例。主要有两个部分:提供用户名和密码以获取令牌;并根据请求检查该令牌。

在此示例中,我们使用了两个库,即Go中的JWT实现以及将其用作中间件的方式。

最后,在使用此代码之前,您需要将APP_KEY常量更改为机密(理想情况下,该常量将存储在代码库外部),并改进用户名/密码检查中的内容,TokenHandler以检查不仅仅是myusername/ mypassword组合。

  1. package main
  2. import (
  3. "io"
  4. "log"
  5. "net/http"
  6. "time"
  7. jwtmiddleware "github.com/auth0/go-jwt-middleware"
  8. "github.com/dgrijalva/jwt-go"
  9. )
  10. const (
  11. APP_KEY = "www.topgoer.com"
  12. )
  13. func main() {
  14. // HTTP Endpoints
  15. // 1. To get a new token
  16. // 2. Our example endpoint which requires auth checking
  17. http.HandleFunc("/token", TokenHandler)
  18. http.Handle("/", AuthMiddleware(http.HandlerFunc(ExampleHandler2)))
  19. // Start a basic HTTP server
  20. if err := http.ListenAndServe(":8080", nil); err != nil {
  21. log.Fatal(err)
  22. }
  23. }
  24. // TokenHandler是我们获取用户名和密码的处理程序,如果有效,则返回用于将来请求的令牌。
  25. func TokenHandler(w http.ResponseWriter, r *http.Request) {
  26. w.Header().Add("Content-Type", "application/json")
  27. r.ParseForm()
  28. // 检查提供的凭据-如果将这些凭据存储在数据库中,则查询将在此处进行检查。
  29. username := r.Form.Get("username")
  30. password := r.Form.Get("password")
  31. if username != "myusername" || password != "mypassword" {
  32. w.WriteHeader(http.StatusUnauthorized)
  33. io.WriteString(w, `{"error":"invalid_credentials"}`)
  34. return
  35. }
  36. // 颁发一个有限期一小时的证书
  37. token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
  38. "user": username,
  39. "exp": time.Now().Add(time.Hour * time.Duration(1)).Unix(),
  40. "iat": time.Now().Unix(),
  41. })
  42. tokenString, err := token.SignedString([]byte(APP_KEY))
  43. if err != nil {
  44. w.WriteHeader(http.StatusInternalServerError)
  45. io.WriteString(w, `{"error":"token_generation_failed"}`)
  46. return
  47. }
  48. io.WriteString(w, `{"token":"`+tokenString+`"}`)
  49. return
  50. }
  51. //AuthMiddleware是我们用来检查令牌是否有效的中间件。如果返回401状态无效,则返回给客户。
  52. func AuthMiddleware(next http.Handler) http.Handler {
  53. if len(APP_KEY) == 0 {
  54. log.Fatal("HTTP server unable to start, expected an APP_KEY for JWT auth")
  55. }
  56. jwtMiddleware := jwtmiddleware.New(jwtmiddleware.Options{
  57. ValidationKeyGetter: func(token *jwt.Token) (interface{}, error) {
  58. return []byte(APP_KEY), nil
  59. },
  60. SigningMethod: jwt.SigningMethodHS256,
  61. })
  62. return jwtMiddleware.Handler(next)
  63. }
  64. func ExampleHandler(w http.ResponseWriter, r *http.Request) {
  65. w.Header().Add("Content-Type", "application/json")
  66. io.WriteString(w, `{"status":"ok"}`)
  67. }
  68. func ExampleHandler2(w http.ResponseWriter, r *http.Request) {
  69. w.Header().Add("Content-Type", "application/json")
  70. io.WriteString(w, `{"status":"ok22222"}`)
  71. }

我们在上面的示例流程中显示,首先获取一个令牌,然后在调用端点时使用该令牌。这些是我们使用的命令:

JSON Web令牌 - 图1

  1. curl -H "Content-Type: application/x-www-form-urlencoded" \
  2. -d "username=myusername&password=mypassword" \
  3. http://localhost:8080/token
  1. curl -H "Authorization: Bearer {{ TOKEN }}" \
  2. -H "Content-Type: application/json" \
  3. http://localhost:8080

gin框架封装jwt链接地址:http://www.topgoer.com/gin框架/其他/生成解析token.html