package main
import (
"net/http"
"github.com/dgrijalva/jwt-go"
)
// 定义JWT的密钥,应该是一个复杂的随机字符串
var jwtKey = []byte("your-256-bit-secret")
// 创建一个JWT令牌
func createJWT(email string) (string, error) {
token := jwt.New(jwt.SigningMethodHS256)
claims := token.Claims.(jwt.MapClaims)
claims["email"] = email
claims["admin"] = true // 假设管理员权限
tokenString, err := token.SignedString(jwtKey)
if err != nil {
return "", err
}
return tokenString, nil
}
// 验证JWT令牌
func validateJWT(tokenString string) (*jwt.Token, error) {
return jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
// 确保令牌的签名算法与我们用于签名的算法匹配
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
return jwtKey, nil
})
}
// 一个简单的HTTP处理函数,用于创建和验证JWT
func jwtHandler(w http.ResponseWriter, r *http.Request) {
// 假设用户已通过身份验证,并且其电子邮件是通过某种方式获得的
email := "user@example.com"
tokenString, err := createJWT(email)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// 返回JWT令牌
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte(`{"token":"` + tokenString + `"}`))
// 验证JWT令牌
token, err := validateJWT(tokenString)
if err != nil {
http.Error(w, err.Error(), http.StatusUnauthorized)
return
}
claims, ok := token.Claims.(jwt.MapClaims)
if ok && token.Valid {
email := claims["email"].(string)
isAdmin := claims["admin"].(bool)
fmt.Fprintf(w, "Email: %s, Admin: %t\n", email, isAdmin)
} else {
http.Error(w, "Invalid token", http.StatusUnauthorized)
}
}
func main() {
http.HandleFunc("/jwt", jwtHandler)
http.ListenAndServe(":8080", nil)
}
这段代码定义了一个简单的HTTP处理函数jwtHandler
,它创建了一个JWT令牌,并返回给客户端。然后,它还验证了这个令牌,并在响应中包含了解析后的声明信息。这个例子展示了如何在实际应用中结合使用JWT库和Go语言进行安全的API验证。