JSON Web Token(JWT)是一种用于身份验证和授权的开放标准。它以紧凑且安全的方式传递信息,它是基于JSON格式和一种自包含的方式来安全传输信息的轻量级的方式。 使用GoJWT可以很方便的实现身份验证和授权,下面就从以下几个方面进行详细的阐述。
一、使用GoJWT生成Token
在Go语言中,我们可以使用第三方库github.com/dgrijalva/jwt-go来完成JWT的生成。下面是一段示例代码:
import (
"github.com/dgrijalva/jwt-go"
"time"
)
func GenerateToken(username string) (string, error) {
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"username": username,
"exp": time.Now().Add(time.Hour * 24).Unix(),
})
tokenString, err := token.SignedString([]byte("jwt-secret-key"))
if err != nil {
return "", err
}
return tokenString, nil
}
在以上示例代码中,`jwt.NewWithClaims()`会返回一个生成的Token对象,而`jwt.MapClaims`是该Token中的一些声明。其中,`exp`字段表示超时时间,在这里设置为1天过期。
二、使用GoJWT进行Token认证
GoJWT也支持Token的认证,以下是一段示例代码:
import (
"github.com/dgrijalva/jwt-go"
"net/http"
"strings"
)
func Authenticate(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
header := r.Header.Get("Authorization")
if header == "" {
w.WriteHeader(http.StatusUnauthorized)
return
}
headerParts := strings.Split(header, " ")
if len(headerParts) != 2 || headerParts[0] != "Bearer" {
w.WriteHeader(http.StatusUnauthorized)
return
}
tokenString := headerParts[1]
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
return []byte("jwt-secret-key"), nil
})
if err != nil || !token.Valid {
w.WriteHeader(http.StatusUnauthorized)
return
}
next.ServeHTTP(w, r)
})
}
以上代码先进行了Token的解析操作,使用`jwt.Parse()`函数可以解析出Token中存储的声明。然后使用`jwt.Valid()`函数验证Token的有效性,如果验证通过,就让`next.ServeHTTP()`函数处理请求,否则返回“401 Unauthorized”响应。
三、使用GoJWT实现权限控制
GoJWT还可以实现简单的权限控制,以下是一个示例代码:
import (
"github.com/dgrijalva/jwt-go"
"net/http"
"strings"
)
func Authorize(roles ...string) func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
header := r.Header.Get("Authorization")
if header == "" {
w.WriteHeader(http.StatusUnauthorized)
return
}
headerParts := strings.Split(header, " ")
if len(headerParts) != 2 || headerParts[0] != "Bearer" {
w.WriteHeader(http.StatusUnauthorized)
return
}
tokenString := headerParts[1]
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
return []byte("jwt-secret-key"), nil
})
if err != nil || !token.Valid {
w.WriteHeader(http.StatusUnauthorized)
return
}
claims, ok := token.Claims.(jwt.MapClaims)
if !ok {
w.WriteHeader(http.StatusUnauthorized)
return
}
claimRoles, ok := claims["roles"].([]interface{})
if !ok {
w.WriteHeader(http.StatusUnauthorized)
return
}
for _, role := range roles {
for _, claimRole := range claimRoles {
if claimRole == role {
next.ServeHTTP(w, r)
return
}
}
}
w.WriteHeader(http.StatusForbidden)
})
}
}
以上代码实现了一个`Authorize()`函数,该函数接收一个或多个角色名称作为参数,然后返回一个HTTP处理器`func(next http.Handler) http.Handler`。该HTTP处理器首先从请求头中获取Token,然后解析Token,如果解析和验证成功,就提取Token中存储的角色信息。最后,该处理器会根据传递的角色参数检查Token中是否包含授权的角色。
四、总结
使用GoJWT可以快速而方便地完成身份验证和授权相关的开发工作。在使用GoJWT过程中,需要注意保证Token的安全性,以免泄露敏感信息。同时,需要进行合理的权限控制,保证系统的稳定性和安全性。