一、JWT是什么?
JSON Web Token(JWT)是一种开放标准(RFC 7519),它定义了一种紧凑的、自包含的格式,用于在各方之间作为JSON对象安全地传输信息。此信息可以被验证和信任,因为它是数字签名的。
JWT有3个部分:头部,载荷和签名。头部包含标识令牌类型和所使用的加密算法。载荷包含声明,例如,用户名、角色等。签名用于验证载荷内容和头部信息是否被篡改。
二、使用Golang创建JWT
Golang提供了第三方库“github.com/dgrijalva/jwt-go”实现JWT的创建。下面是代码示例:
import ( "github.com/dgrijalva/jwt-go" "time" ) func createToken(username, role string) (string, error) { token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ "username": username, "role": role, "timestamp": time.Now().Unix(), }) tokenString, err := token.SignedString([]byte("secret")) if err != nil { return "", err } return tokenString, nil }
我们首先导入“github.com/dgrijalva/jwt-go”这个第三方库,并编写createToken函数来创建JWT。createToken函数接收2个参数:用户名和角色,然后生成一个JWT令牌。
在这里,我们首先创建一个jwt.NewWithClaims对象,指定签名算法为HS256。然后使用jwt.MapClaims保存用户的声明,例如用户名、角色和时间戳。最后使用签名密钥“secret”对JWT进行数字签名,并将其返回给调用者。
三、使用Golang验证JWT
在使用JWT进行身份验证之前,我们需要在服务器端对其进行验证。
Golang提供了第三方库“github.com/dgrijalva/jwt-go”实现JWT的验证。下面是代码示例:
import ( "errors" "github.com/dgrijalva/jwt-go" "time" ) func parseToken(tokenString string) (jwt.MapClaims, error) { token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { return nil, errors.New("unexpected signing method") } return []byte("secret"), nil }) if err != nil { return nil, err } claims, ok := token.Claims.(jwt.MapClaims) if !ok || !token.Valid { return nil, errors.New("token is invalid") } if claims.VerifyExpiresAt(time.Now().Unix(), true) == false { return nil, errors.New("token has expired") } return claims, nil }
我们首先导入“github.com/dgrijalva/jwt-go”这个第三方库,并编写parseToken函数来验证JWT。parseToken函数接收一个JWT令牌字符串,并将其解析为一个jwt.MapClaims对象。
在这里,我们首先使用jwt.Parse函数将JWT令牌字符串解析为一个Jwt.Token对象,其中包含了头部、载荷和签名等信息。如果JWT签名的签名算法不是HS256,则返回错误。如果签名的密钥不正确,则无法验证JWT令牌的有效性。如果JWT的载荷不是jwt.MapClaims类型,或者JWT不是有效的,则返回错误。
在Jwt.MapClaims对象中,我们可以访问JWT令牌的声明信息和时间戳信息。在这里,我们对JWT令牌的时间戳进行了验证,以确保JWT令牌没有过期。
四、结论
JWT是一种安全和可靠的身份验证机制,它可以在嵌入式、移动和Web应用程序中使用。在本文中,我们使用Golang实现了JWT的认证和验证,代码简单易懂。