用户认证
用户向服务器发送用户名和密码。验证服务器后,相关数据(如用户名,用户角色等)将保存在当前会话(session)中。服务器向用户返回 session_id,session 信息都会写入到用户的 Cookie。用户的每个后续请求都将通过在 Cookie 中取出 session_id 传给服务器。服务器收到 session_id 并对比之前保存的数据,确认用户的身份。
上述过程讲解用户认证的过程,用户认证也就是登陆过程,登陆成功就可以进行后续操作。
Token模式
JWT介绍
JWT 是 JSON Web Token 的缩写,即 JSON Web 令牌,是一种自包含令牌。
JWT 的使用场景:
- 一种情况是 webapi,类似之前的阿里云播放凭证的功能
- 另一种情况是多 web 服务器下实现无状态分布式身份验证
JWT的作用:
JWT 最重要的作用就是对 token 信息的防伪作用 JWT 的原理:
一个 JWT 由三个部分组成:JWT 头、有效载荷、签名哈希 最后由这三者组合进行 base64 编码得到 JWT JWT的用法:
客户端接收服务器返回的 JWT,将其存储在 Cookie 或 localStorage 中
此后,客户端将在与服务器交互中都会带 JWT。如果将它存储在 Cookie 中,就可以自动发送,但是不会跨域,因此一般是将它放入 HTTP 请求的 Header Authorization 字段中。
Token 模式是一种身份验证和授权的方案,而 JWT 则是 Token 模式的一种具体实现方式,其中 JWT 是基于 JSON 的开放标准,并且具有一定的特性和优势。
在gin框架使用JWT
go get "github.com/golang-jwt/jwt/v4"
通过这段可以下载JWT相关库。
JWT引入
JWT的引入是方便我们进行用户认证。用户认证最简单的就是需要账号和密码,那么我们就需要在客户端接收账号和密码,然后进行验证。
生成JWT
func GenerateJWT(userName string) (string, error) {
claims := jwt.MapClaims{
"id": userName,
"exp": time.Now().Add(time.Hour * 24).Unix(),
"iss": "your-app",
"iat": time.Now().Unix(),
}
token := jwt.NewWithClaims(jwt.SigningMethodES256, claims)
return token.SigningString()
}
-
创建一个包含用户信息的声明
claims。在这个例子中,声明中包含以下字段:"id": 用户名(或用户ID),将作为用户标识。"exp": Token 的过期时间,设定为当前时间加上一天的时间间隔,表示 Token 在一天后过期。"iss": Token 的签发者,可以是你的应用程序名称或标识。"iat": Token 的签发时间,设定为当前时间。
-
使用声明
claims创建一个新的 JWT Token。jwt.NewWithClaims函数来自github.com/golang-jwt/jwt/v4包,它接收两个参数:签名方法和声明。jwt.SigningMethodES256表示使用 ECDSA 256 位算法作为签名方法。claims是之前创建的声明。
-
调用
SigningString方法来生成 JWT Token 的字符串表示。SigningString是 JWT Token 对象提供的方法,它会生成一个用于签名的字符串。- 返回的字符串是符合 JWT 标准的字符串结果,可以直接用于传输或存储。
-
返回生成的 JWT Token 字符串。
将返回的密文进行解密
解密JWT
func ParseJWT(tokenString string) (*jwt.MapClaims, error) {
claims, err := jwt.ParseWithClaims(tokenString, &jwt.MapClaims{}, func(token *jwt.Token) (interface{}, error) {
return secretKey, nil
})
if err != nil {
return nil, err
}
mapClaims := claims.Claims.(*jwt.MapClaims)
if !claims.Valid || mapClaims.Valid() != nil {
return nil, fmt.Errorf("error")
}
return mapClaims, nil
}
-
接收一个 JWT Token 字符串
tokenString作为参数。 -
使用
jwt.ParseWithClaims函数解析 JWT Token,并将解析后的声明存储在claims变量中。- 第一个参数
tokenString是要解析的 JWT Token 字符串。 - 第二个参数
&jwt.MapClaims{}是一个空的jwt.MapClaims对象指针,用于存储解析后的声明信息。 - 第三个参数是一个回调函数,用于提供用于验证签名的密钥。在这里,回调函数返回固定的
secretKey(密钥)。
- 第一个参数
-
检查解析过程中的错误。如果解析失败,将返回
nil和解析过程中的错误。 -
将声明信息的类型断言为
*jwt.MapClaims,并将其存储在mapClaims变量中。claims.Claims是一个jwt.Claims接口类型,包含了解析后的声明信息。- 通过将
claims.Claims类型断言为*jwt.MapClaims,可以将其转换为具体的声明类型。
-
检查 Token 的有效性。如果 Token 无效或其中的声明信息无效(如过期),将返回一个包含错误信息的
fmt.Errorf。 -
返回解析后的声明信息
mapClaims。mapClaims是一个指向解析后的声明信息的指针。1. 接收一个 JWT Token 字符串tokenString作为参数。
-
使用
jwt.ParseWithClaims函数解析 JWT Token,并将解析后的声明存储在claims变量中。- 第一个参数
tokenString是要解析的 JWT Token 字符串。 - 第二个参数
&jwt.MapClaims{}是一个空的jwt.MapClaims对象指针,用于存储解析后的声明信息。 - 第三个参数是一个回调函数,用于提供用于验证签名的密钥。在这里,回调函数返回固定的
secretKey(密钥)。
- 第一个参数
-
检查解析过程中的错误。如果解析失败,将返回
nil和解析过程中的错误。 -
将声明信息的类型断言为
*jwt.MapClaims,并将其存储在mapClaims变量中。claims.Claims是一个jwt.Claims接口类型,包含了解析后的声明信息。- 通过将
claims.Claims类型断言为*jwt.MapClaims,可以将其转换为具体的声明类型。
-
检查 Token 的有效性。如果 Token 无效或其中的声明信息无效(如过期),将返回一个包含错误信息的
fmt.Errorf。 -
返回解析后的声明信息
mapClaims。mapClaims是一个指向解析后的声明信息的指针。
总结
用户认证其实就是登陆的过程。如何有效的进行用户身份验证,减轻服务器访问压力。对于敏感内容需要二次认证,还有减短其有效时间,以保证用户信息的安全。