我是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))
})
}
2条答案
按热度按时间b91juud31#
由于你是在要求标头中检查标记
x-access-token
,所以你需要在传送要求时加入相同的标记。这可以在Postman中轻松完成,如下所示-我用的路由器是-
程序包干线
我用的中间件是-
包授权
而处理人是-
软件包中间件
fnvucqvd2#
您可以在授权部分传递令牌: