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()
}

源代码:https://gitee.com/zly233/gf-jwt.git

posted @ 2021-07-12 15:52  悠悠听风  阅读(1243)  评论(1编辑  收藏  举报