golang進行簡單權限認證的實現
使用JWT進行認證
JSON Web Tokens (JWT) are a more modern approach to authentication.
As the web moves to a greater separation between the client and server, JWT provides a wonderful alternative to traditional cookie based authentication models.
JWTs provide a way for clients to authenticate every request without having to maintain a session or repeatedly pass login credentials to the server.
用戶註冊之後, 服務器生成一個 JWT token返回給瀏覽器, 瀏覽器向服務器請求數據時將 JWT token 發給服務器, 服務器用 signature 中定義的方式解碼
JWT 獲取用戶信息.
一個 JWT token包含3部分:
1 header: 告訴我們使用的算法和 token 類型
2 Payload: 必須使用 sub key 來指定用戶 ID, 還可以包括其他信息比如 email, username 等.
3 Signature: 用來保證 JWT 的真實性. 可以使用不同算法
package main import ( "encoding/json" "fmt" "log" "net/http" "strings" "time" "github.com/codegangsta/negroni" "github.com/dgrijalva/jwt-go" "github.com/dgrijalva/jwt-go/request" ) const ( SecretKey = "welcome ---------" ) func fatal(err error) { if err != nil { log.Fatal(err) } } type UserCredentials struct { Username string `json:"username"` Password string `json:"password"` } type User struct { ID int `json:"id"` Name string `json:"name"` Username string `json:"username"` Password string `json:"password"` } type Response struct { Data string `json:"data"` } type Token struct { Token string `json:"token"` } func StartServer() { http.HandleFunc("/login", LoginHandler) http.Handle("/resource", negroni.New( negroni.HandlerFunc(ValidateTokenMiddleware), negroni.Wrap(http.HandlerFunc(ProtectedHandler)), )) log.Println("Now listening...") http.ListenAndServe(":8087", nil) } func main() { StartServer() } func ProtectedHandler(w http.ResponseWriter, r *http.Request) { response := Response{"Gained access to protected resource"} JsonResponse(response, w) } func LoginHandler(w http.ResponseWriter, r *http.Request) { var user UserCredentials err := json.NewDecoder(r.Body).Decode(&user) if err != nil { w.WriteHeader(http.StatusForbidden) fmt.Fprint(w, "Error in request") return } if strings.ToLower(user.Username) != "someone" { if user.Password != "p@ssword" { w.WriteHeader(http.StatusForbidden) fmt.Println("Error logging in") fmt.Fprint(w, "Invalid credentials") return } } token := jwt.New(jwt.SigningMethodHS256) claims := make(jwt.MapClaims) claims["exp"] = time.Now().Add(time.Hour * time.Duration(1)).Unix() claims["iat"] = time.Now().Unix() token.Claims = claims if err != nil { w.WriteHeader(http.StatusInternalServerError) fmt.Fprintln(w, "Error extracting the key") fatal(err) } tokenString, err := token.SignedString([]byte(SecretKey)) if err != nil { w.WriteHeader(http.StatusInternalServerError) fmt.Fprintln(w, "Error while signing the token") fatal(err) } response := Token{tokenString} JsonResponse(response, w) } func ValidateTokenMiddleware(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) { token, err := request.ParseFromRequest(r, request.AuthorizationHeaderExtractor, func(token *jwt.Token) (interface{}, error) { return []byte(SecretKey), nil }) if err == nil { if token.Valid { next(w, r) } else { w.WriteHeader(http.StatusUnauthorized) fmt.Fprint(w, "Token is not valid") } } else { w.WriteHeader(http.StatusUnauthorized) fmt.Fprint(w, "Unauthorized access to this resource") } } func JsonResponse(response interface{}, w http.ResponseWriter) { json, err := json.Marshal(response) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.WriteHeader(http.StatusOK) w.Header().Set("Content-Type", "application/json") w.Write(json) }
到此這篇關於golang進行簡單權限認證的實現的文章就介紹到這瞭,更多相關golang 權限認證內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- golang中gin框架接入jwt使用token驗證身份
- go gin+token(JWT)驗證實現登陸驗證
- 基於Go語言構建RESTful API服務
- 解決Golang中ResponseWriter的一個坑
- golang 實現Location跳轉方式