该系列源码已开源:micro-shop
JWT
?JSON Web令牌(JWT)是一个开放标准(RFC 7519),它定义了一种紧凑而独立的方法,用于在各方之间安全地将信息作为JSON对象传输。由于此信息是经过数字签名的,因此可以被验证和信任。可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公钥/私钥对对JWT进行签名。
JWT
?授权:这是使用JWT
的最常见方案。一旦用户登录,每个后续请求将包括JWT
,从而允许用户访问该令牌允许的路由,服务和资源。单一登录是当今广泛使用JWT
的一项功能,因为它的开销很小并且可以在不同的域中轻松使用。
信息交换:JSON Web
令牌是在各方之间安全地传输信息的一种好方法。因为可以对JWT
进行签名(例如,使用公钥/私钥对
),所以您可以确保发件人是他们所说的人。此外,由于签名是使用标头和有效负载计算的,因此您还可以验证内容是否未被篡改。
JSON Web
令牌 ?由于JSON
不如XML
冗长,因此在编码时JSON
的大小也较小,从而使JWT
比SAML
更为紧凑。这使得JWT
是在HTML
和HTTP
环境中传递的不错的选择。
在安全方面,只能使用HMAC算法由共享机密对SWT
进行对称签名。但是,JWT
和SAML
令牌可以使用X.509
证书形式的公用/专用密钥对
进行签名。与签署JSON
的简单性相比,使用XML Digital Signature
签署XML
而不引入模糊的安全漏洞是非常困难的。
JSON
解析器在大多数编程语言中都很常见,因为它们直接映射到对象。相反,XML
没有自然的文档到对象的映射。与SAML
断言相比,这使使用JWT
更加容易。
关于用法,JWT
是在Internet
规模上使用的。这突显了在多个平台(尤其是移动平台)上对JSON Web
令牌进行客户端处理的简便性。
注意:
以上内容全部来自 jwt官网介绍
如果历史文章不是很清楚的,可通过如下传送门:
JWT
jwt
鉴权一般在api
层使用,在这里咱们是用在用户服务
上面的。
具体步骤:
user api
jwt token
jwt token
user api
添加配置定义
vim user/api/internal/config/config.go
type Config struct {
rest.RestConf
SecretKey string
Auth struct {
AccessSecret string
AccessExpire int64
}
}
配置yaml
配置项
vim user/api/etc/user-api.yaml
# user 模块配置
Name: user-api
Host: 0.0.0.0
Port: 9001
SecretKey: C8xHnG6s
Auth:
AccessSecret: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
AccessExpire: 64800
AccessSecret
:生成jwt token
的密钥,最简单的方式可以使用一个uuid
值。
AccessExpire
:jwt token
有效期,单位:秒
jwt token
生成
vim user/api/internal/logic/login-logic.go
func (l *LoginLogic) GetToken(iat int64, secretKey string, payloads map[string]any, seconds int64) (string, error) {
claims := make(jwt.MapClaims)
claims["expTime"] = iat + seconds
claims["iat"] = iat
for k, v := range payloads {
claims[k] = v
}
token := jwt.New(jwt.SigningMethodHS256)
token.Claims = claims
return token.SignedString([]byte(secretKey))
}
使用
payloads := make(map[string]any)
payloads["userIdentity"] = userData.UserIdentity
accessToken, tokenErr := l.GetToken(time.Now().Unix(), l.svcCtx.Config.Auth.AccessSecret, payloads, l.svcCtx.Config.Auth.AccessExpire)
if tokenErr != nil {
return nil, tokenErr
}
jwt token
编写user.api
文件
vim user/api/user.api
type (
UserInfoReq struct{}
UserInfoResply {
Code int64 `json:"Code"`
Message string `json:"Message"`
Data *UserInfoItem `json:"Data"`
}
UserInfoItem {
UserIdentity string `json:"UserIdentity"` // 用户唯一表哦是
UserName string `json:"UserName"` // 用户名
UserNick string `json:"UserNick"` // 用户昵称
UserFace string `json:"UserFace"` // 用户头像地址
UserSex int64 `json:"UserSex"` // 用户性别:0男,1女,2保密
UserEmail string `json:"UserEmail"` // 用户邮箱
UserPhone string `json:"UserPhone"` // 用户手机号
}
)
@server(
jwt: Auth
)
service user-api{
@doc (
summary: "用户信息"
)
@handler userInfo
post /userinfo (UserInfoReq) returns (UserInfoResply)
}
jwt: Auth
:开启jwt
鉴权
如果路由需要jwt
鉴权,则需要在service
上方声明此语法标志
不需要jwt
鉴权的路由就无需声明
jwt token
中携带的信息
go-zero
从jwt token
解析后会将用户生成token
时传入的kv
原封不动的放在http.Request的Context
中,因此我们可以通过Context
就可以拿到你想要的值
vim user/api/internal/logic/user-info-logic.go
func (l *UserInfoLogic) UserInfo(req types.UserInfoReq) (resp *types.UserInfoResply, err error) {
userIdentity := fmt.Sprintf("%v", l.ctx.Value("userIdentity"))
// 这里的key和生成jwt token时传入的key一致
logx.Infof("userId: %v",userIdentity)
return &types.UserInfoResply{}, nil
}
本篇文章介绍说明了在开发过程中会出现的一些清情况:
JWT
JWT Token
JWT Token
生效另外,如果你感兴趣,非常欢迎你加入,我们一起来完成这个项目,为社区献出自己的一份力。
希望本篇文章对你有所帮助,谢谢。