- Created by FLY的狐狸, last modified on Dec 28, 2020
安装教程
- gopath模式:
go get github.com/goflyfox/gtoken
- 或者 使用go.mod添加 :
require github.com/goflyfox/gtoken latest
分组中间件实现
GoFrame官方推荐使用Group方式实现路由和中间件;
使用说明
推荐使用分组方式实现
Golang
// 启动gtoken gfToken := >oken.GfToken{ LoginPath: "/login", LoginBeforeFunc: loginFunc, LogoutPath: "/user/logout", } s.Group("/admin", func(group *ghttp.RouterGroup) { group.Middleware(CORS) gfToken.Middleware(group) group.ALL("/system/user", func(r *ghttp.Request) { r.Response.WriteJson(gtoken.Succ("system user")) }) ……………… })
登录方法实现,通过username返回空或者r.ExitAll()\r.Exit()处理认证失败;
特别提示:这里注册的路径严格按照GF group方式,所以注册的路径是/admin/login
和/admin/user/logout
func Login(r *ghttp.Request) (string, interface{}) { username := r.GetPostString("username") passwd := r.GetPostString("passwd") // TODO 进行登录校验 if username == "" || passwd == "" { r.Response.WriteJson(gtoken.Fail("账号或密码错误.")) r.ExitAll() } return username, "" }
通过gtoken.GetTokenData(r)
获取登录信息
路径拦截规则
AuthExcludePaths: g.SliceStr{"/user/info", "/system/user/*"}, // 不拦截路径 /user/info,/system/user/info,/system/user,
- 分组中间件实现,不需要设置
AuthPaths
认证路径,设置也没有作用,需要认证路径为该分组下所有路由; - 使用分组拦截的是通过GoFrame的
group.Middleware(authMiddleware)
方法,对该分组下的所有路由进行拦截; - 对登录接口路径
loginPath
和登出接口路径logoutPath
做拦截认证放行,登出放行是为了避免认证过期无法登出情况; - 严格按照GoFrame分组中间件拦截优先级;如果使用跨域中间件,建议放在跨域中间件之后;
- 如果配置
AuthExcludePaths
路径,会将配置的不拦截路径排除;
逻辑测试
参考sample项目,先运行main.go,然后可运行api_test.go进行测试并查看结果;验证逻辑说明:
- 访问用户信息,提示未携带token
- 调用登录后,携带token访问正常
- 调用登出提示成功
- 携带之前token访问,提示未登录
=== RUN TestAdminSystemUser api_admin_test.go:22: 1. not login and visit user api_admin_test.go:29: {"code":-401,"msg":"请求错误或登录超时","data":""} api_admin_test.go:42: 2. execute login and visit user api_admin_test.go:45: {"code":0,"msg":"success","data":"system user"} api_admin_test.go:51: 3. execute logout api_admin_test.go:54: {"code":0,"msg":"success","data":"Logout success"} api_admin_test.go:60: 4. visit user api_admin_test.go:65: {"code":-401,"msg":"请求错误或登录超时","data":""}
全局中间件实现
使用说明
只需要配置登录路径、登出路径、拦截路径以及登录校验实现即可
// 启动gtoken gtoken := >oken.GfToken{ LoginPath: "/login", LoginBeforeFunc: loginFunc, LogoutPath: "/user/logout", AuthPaths: g.SliceStr{"/user", "/system"}, // 这里是按照前缀拦截,拦截/user /user/list /user/add ... GlobalMiddleware: true, // 开启全局拦截,默认关闭 } gtoken.Start()
登录方法实现,通过username返回空或者r.ExitAll()\r.Exit()处理认证失败;
func Login(r *ghttp.Request) (string, interface{}) { username := r.GetPostString("username") passwd := r.GetPostString("passwd") // TODO 进行登录校验 if username == "" || passwd == "" { r.Response.WriteJson(gtoken.Fail("账号或密码错误.")) r.ExitAll() } return username, "" }
通过gtoken.GetTokenData(r)
获取登录信息
路径拦截规则
AuthPaths: g.SliceStr{"/user", "/system"}, // 这里是按照前缀拦截,拦截/user /user/list /user/add ... AuthExcludePaths: g.SliceStr{"/user/info", "/system/user/*"}, // 不拦截路径 /user/info,/system/user/info,/system/user, GlobalMiddleware: true, // 开启全局拦截,默认关闭
GlobalMiddleware:true
全局拦截的是通过GF的BindMiddleware
方法创建拦截/*
GlobalMiddleware:false
路径拦截的是通过GF的BindMiddleware
方法创建拦截/user*和/system/*
- 按照中间件优先级路径拦截优先级很高;如果先实现部分中间件在认证前处理需要切换成全局拦截器,严格按照注册顺序即可;
- 程序先处理认证路径,如果满足;再排除不拦截路径;
- 如果只想用排除路径功能,将拦截路径设置为
/*
即可;
逻辑测试
参考sample1项目,先运行main.go,然后可运行api_test.go进行测试并查看结果;验证逻辑说明:
- 访问用户信息,提示未携带token
- 调用登录后,携带token访问正常
- 调用登出提示成功
- 携带之前token访问,提示未登录
=== RUN TestSystemUser api_test.go:43: 1. not login and visit user api_test.go:50: {"code":-401,"msg":"请求错误或登录超时","data":""} api_test.go:63: 2. execute login and visit user api_test.go:66: {"code":0,"msg":"success","data":"system user"} api_test.go:72: 3. execute logout api_test.go:75: {"code":0,"msg":"success","data":"Logout success"} api_test.go:81: 4. visit user api_test.go:86: {"code":-401,"msg":"请求错误或登录超时","data":""}
返回码及配置项
- 正常操作成功返回0
- 未登录访问需要登录资源返回401
- 程序异常返回-99,如编解码错误等
SUCCESS = 0 // 正常 FAIL = -1 // 失败 ERROR = -99 // 异常 UNAUTHORIZED = -401 // 未认证
Content Menu
- No labels
10 Comments
iamyl
这个错误返回方式固定了之后,无法接管,用起来非常不方便
FLY的狐狸
这个只是框架的规范,建议这种格式;
其实返回值是可以通过方法自己实现的,可以看下初始化参数,根据自己的需求来
kk
有具体的案例嘛 怎么按照自己的想返回的错误码来做
小菜鸟儿
王中阳Go
GoFrame集成gtoken视频详解,包括v2和v1两个版本: https://www.bilibili.com/video/BV1v841157Bh/
强仔
您好 狐狸老师,我在更新到2.0后,因为登陆前和登陆后的方法都没有框架规范的Ctx 参数。
佟巨华
登录函数里面可以设置,比如验证完用户可以登录,那就SetUser信息就可以了
王中阳Go
【视频教程】GoFrame集成gtoken视频详解,包括v2版本和v1版本。https://www.bilibili.com/video/BV1v841157Bh/
zhangpanpan
怎么销毁token的有效期呢 也就是说怎么退出登陆呢
labixiaoxin
为什么cmd运行有gtoken的相关接口,生成的swagger没有gtoken相关的接口