GoFrame框架使用jwt认证
gf-jwt插件地址:https://github.com/gogf/gf-jwt
GoFrame框架地址:https://goframe.org/display/gf
首先引入gf-jwt
下载安装
$ go get github.com/gogf/gf-jwt
导入
import "github.com/gogf/gf-jwt"
定义自己的登录鉴权以及jwt相关配置需要重写gf-jwt的初始化函数
var GfJWTMiddleware *jwt.GfJWTMiddleware
func init() {
middleware, err := jwt.New(&jwt.GfJWTMiddleware{
Realm: "KanXun_vr", //领域名称
Key: g.Cfg().GetBytes("JWT.MySecret"), //签名秘钥
Timeout: time.Minute * 60, //过期时间
MaxRefresh: time.Minute * 5, //token过期后,可凭借旧token获取新token的刷新时间
IdentityKey: "id", // 身份验证的key值
TokenLookup: "header: Authorization, query: token, cookie: jwt", // token检索模式,用于提取token-> Authorization
TokenHeadName: "Bearer", // token在请求头时的名称,默认值为Bearer
// 客户端在header中传入Authorization 对一个值是Bearer + 空格 + token
//TimeFunc: time.Now, // 测试或服务器在其他时区可设置该属性
Authenticator: api.User.Login, // 根据登录信息对用户进行身份验证的回调函数
Unauthorized: auth.Unauthorized, // 处理不进行授权的逻辑
IdentityHandler: auth.IdentityHandler, // 解析并设置用户身份信息
PayloadFunc: auth.PayloadFunc, // 登录期间的回调的函数
LoginResponse: api.User.LoginResponse, // 登录成功后的响应,在此处添加数据到redis
LogoutResponse: api.User.LogoutResponse, //注销/token无效化(黑名单)处理后返回的信息,用户可自定义返回数据
})
if err != nil {
g.Log().Error(err)
return
}
GfJWTMiddleware = middleware
}
在此贴上gf-jwt相关的配置说明
https://goframe.org/pages/viewpage.action?pageId=6357048
重写gf-jwt配置的登录验证方法
//Authenticator: api.User.Login, 根据登录信息对用户进行身份验证的回调函数
// Login 用户登录
func (*userApi) Login(r *ghttp.Request) (interface{}, error) {
userName := r.GetString("username")
id, err := service.Login(userName)
if err != nil {
//g.Log().Error("异常错误")
if errors.Is(err, response.ErrorUserNotExist) {
//response.JsonExit(r, 1, "no", "用户不存在")
return nil, response.ErrorUserNotExist
}
if errors.Is(err, response.ErrorDataException) {
//response.JsonExit(r, 1, "no", "数据异常")
return nil, response.ErrorDataException
}
}
//到redis中查询id,是否当前用户登陆过
userIS, err := dao.UsUser.QueryUserIDRedis(id)
if userIS {
//返回重复登录,请重新登录
return nil, response.ErrorUserRepetition
}
//传递id值到r中
r.SetParam("id", id)
return g.Map{
"id": id,
"username": userName,
}, nil
}
重写登录成功后的响应
//LoginResponse: api.User.LoginResponse, 登录成功后的响应,在此处添加数据到redis
// LoginResponse 登录成功后的响应函数,在此存储数据到redis
func (*userApi) LoginResponse(r *ghttp.Request, code int, token string, expire time.Time) {
//调用redis存储数据
err := dao.UsUser.SetUserNameRedis(token, gconv.Int64(r.GetParam("id")))
if err != nil {
g.Log().Error(" redis.Rdb.Set()异常", err)
return
}
err = r.Response.WriteJson(g.Map{
"code": http.StatusOK,
"token": token,
"expire": expire.Format(time.RFC3339),
})
if err != nil {
g.Log().Error("r.Response.WriteJson()解析失败", err)
return
}
r.ExitAll()
}
重写注销token无效化处理,此处需配置MaxRefresh
// LogoutResponse: api.User.LogoutResponse, 注销/token无效化(黑名单)处理后返回的信息,用户可自定义返回数据
// LogoutResponse 注销成功,删除redis中的数据
func (*userApi) LogoutResponse(r *ghttp.Request, code int) {
err := dao.UsUser.DeleteUserIDRedis(gconv.Int64(r.GetParam("id")))
if err != nil {
g.Log().Error(" dao.UsUser.DeleteUserIDRedis()异常", err)
return
}
err = r.Response.WriteJson(g.Map{
"code": code,
"message": "success",
})
if err != nil {
g.Log().Error("r.Response.WriteJson()解析失败", err)
return
}
r.ExitAll()
}