Golang -我如何获得mux的授权?

lnlaulya  于 2023-03-10  发布在  Go
关注(0)|答案(2)|浏览(115)

我是Golang的初学者,我开始用 JWT 学习Gorilla/Mux。
我刚刚成功地注册了一个用户到MongoDB然后登录。我使用Postman来测试。但是当我尝试浏览到受保护的路由时。我得到了错误“丢失授权令牌”,就像我在验证中遇到的一样。
Postman 如何取得浏览受保护路线的授权?
以下是注册和登录代码:
路由器功能

func Router() *mux.Router {

    router := mux.NewRouter().StrictSlash(true)
  router.Use(CommonMiddleware)

  //router.HandleFunc("/", middleware.TestAPI).Methods("GET", "OPTIONS")
  router.HandleFunc("/register", middleware.RegisterHandler).Methods("POST", "OPTIONS")
  router.HandleFunc("/login", middleware.LoginHandler).Methods("POST", "OPTIONS")

  secure := router.PathPrefix("/auth").Subrouter()
  secure.Use(auth.JwtVerify)

    secure.HandleFunc("/api/task", middleware.GetAllTask).Methods("GET", "OPTIONS")
    secure.HandleFunc("/api/task", middleware.CreateTask).Methods("POST", "OPTIONS")
    secure.HandleFunc("/api/task/{id}", middleware.TaskComplete).Methods("PUT", "OPTIONS")
    secure.HandleFunc("/api/undoTask/{id}", middleware.UndoTask).Methods("PUT", "OPTIONS")
    secure.HandleFunc("/api/deleteTask/{id}", middleware.DeleteTask).Methods("DELETE", "OPTIONS")
    secure.HandleFunc("/api/deleteAllTask", middleware.DeleteAllTask).Methods("DELETE", "OPTIONS")
    return router
}

func CommonMiddleware(next http.Handler) http.Handler {
  return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    w.Header().Add("Content-Type", "application/json")
    w.Header().Set("Access-Control-Allow-Origin", "*")
    w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
    w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, Access-Control-Request-Headers, Access-Control-Request-Method, Connection, Host, Origin, User-Agent, Referer, Cache-Control, X-header")
    next.ServeHTTP(w, r)
  })
}

寄存器功能

func RegisterHandler(w http.ResponseWriter, r *http.Request) {
  w.Header().Set("Content-Type", "application/json")
  var user models.User
  body, _ := ioutil.ReadAll(r.Body)
  err := json.Unmarshal(body, &user)
  var res models.ResponseResult
  if err != nil {
    res.Error = err.Error()
    json.NewEncoder(w).Encode(res)
    return
  }

  var result models.User
  err = usercollection.FindOne(context.TODO(), bson.D{{"username", user.Username}}).Decode(&result)

  if err != nil {
    if err.Error() == "mongo: no documents in result" {
      hash, err := bcrypt.GenerateFromPassword([]byte(user.Password), 5)

      if err != nil {
        res.Error = "Error While Hashing Password, Try Again"
        json.NewEncoder(w).Encode(res)
        return
      }
      user.Password = string(hash)

      _, err = usercollection.InsertOne(context.TODO(), user)
      if err != nil {
        res.Error = "Error While Creating User, Try Again"
        json.NewEncoder(w).Encode(res)
        return
      }
      res.Result = "Register Successful"
      json.NewEncoder(w).Encode(res)
      return
    }
    res.Error = err.Error()
    json.NewEncoder(w).Encode(res)
    return
  }
  res.Result = "Username already exists!!"
  json.NewEncoder(w).Encode(res)
  return
}

登录功能

func LoginHandler(w http.ResponseWriter, r *http.Request) {
  w.Header().Set("Content-Type", "application/json")
  var user models.User
  body, _ := ioutil.ReadAll(r.Body)
  err := json.Unmarshal(body, &user)

  if err != nil {
    log.Fatal(err)
  }
  //var resultToken models.Token
  var resultUser models.User
  var res models.ResponseResult

  err = usercollection.FindOne(context.TODO(), bson.D{{"username", user.Username}}).Decode(&resultUser)

  if err != nil {
    res.Error = "Invalid username"
    json.NewEncoder(w).Encode(res)
    return
  }

  expiresAt := time.Now().Add(time.Minute * 100000).Unix()

  errf := bcrypt.CompareHashAndPassword([]byte(resultUser.Password), []byte(user.Password))

  if errf != nil && errf == bcrypt.ErrMismatchedHashAndPassword {
    var  res = map[string]interface{}{"status": false, "message": "Invalid login credential. Please try again"}
    json.NewEncoder(w).Encode(res)
    return
  }
  tk := &models.Token{
    Username: user.Username,
    StandardClaims: &jwt.StandardClaims{
      ExpiresAt: expiresAt,
    },
  }

  token := jwt.NewWithClaims(jwt.GetSigningMethod("HS256"), tk)

  tokenString, err := token.SignedString([]byte("secret"))

  if err != nil {
    res.Error = "Error while generating token, Try again"
    json.NewEncoder(w).Encode(res)
    return
  }
  var resp = map[string]interface{}{"status": false, "message": "logged in"}
  resp["token"] = tokenString
  resp["tk"] = tk

  json.NewEncoder(w).Encode(resp)
}

验证功能

func JwtVerify(next http.Handler) http.Handler {
  return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    var header = r.Header.Get("x-access-token")

    json.NewEncoder(w).Encode(r)
    header = strings.TrimSpace(header)

    if header == "" {
      w.WriteHeader(http.StatusForbidden)
      json.NewEncoder(w).Encode(Exception{Message: "Missing auth token"})
      return
    }

    tk := &models.Token{}

    _, err := jwt.ParseWithClaims(header, tk, func(token *jwt.Token) (interface{}, error) {
      return []byte("secret"), nil
    })

    if err != nil {
      w.WriteHeader(http.StatusForbidden)
      json.NewEncoder(w).Encode(Exception{Message: err.Error()})
      return
    }

    ctx := context.WithValue(r.Context(), "user", tk)
    next.ServeHTTP(w, r.WithContext(ctx))
  })
}
b91juud3

b91juud31#

由于你是在要求标头中检查标记x-access-token,所以你需要在传送要求时加入相同的标记。这可以在Postman中轻松完成,如下所示-

我用的路由器是-
程序包干线

func router() *mux.Router {
    router := mux.NewRouter().StrictSlash(true)
    secure := router.PathPrefix("/auth").Subrouter()
    secure.Use(auth.JwtVerify)
    secure.HandleFunc("/api", middleware.ApiHandler).Methods("GET")
    return router
}

func main() {
    r := router()
    http.ListenAndServe(":8080", r)
}

我用的中间件是-
包授权

func JwtVerify(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        var header = r.Header.Get("x-access-token")

        json.NewEncoder(w).Encode(r)
        header = strings.TrimSpace(header)

        if header == "" {
            w.WriteHeader(http.StatusForbidden)
            json.NewEncoder(w).Encode("Missing auth token")
            return
        } else {
            json.NewEncoder(w).Encode(fmt.Sprintf("Token found. Value %s", header))
        }
        next.ServeHTTP(w, r)
    })
}

而处理人是-
软件包中间件

func ApiHandler(w http.ResponseWriter, r *http.Request) {
    w.WriteHeader(http.StatusOK)
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode("SUCCESS!")
    return
}
fnvucqvd

fnvucqvd2#

您可以在授权部分传递令牌:

相关问题