From 0ea6e7a4ac8596f1a8b890450a62acff52586658 Mon Sep 17 00:00:00 2001 From: songzhibin97 <718428482@qq.com> Date: Sun, 29 Aug 2021 18:23:52 +0800 Subject: [PATCH 1/7] =?UTF-8?q?feat:ws=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/go.mod | 29 +++++++++++- server/initialize/plugin.go | 6 ++- server/plugin/ws/utils/utils.go | 52 +++++++++++++++++++++ server/plugin/ws/ws.go | 83 +++++++++++++++++++++++++++++++++ 4 files changed, 167 insertions(+), 3 deletions(-) create mode 100644 server/plugin/ws/utils/utils.go create mode 100644 server/plugin/ws/ws.go diff --git a/server/go.mod b/server/go.mod index 3b15d01b..d9d48b24 100644 --- a/server/go.mod +++ b/server/go.mod @@ -3,33 +3,58 @@ module github.com/flipped-aurora/gin-vue-admin/server go 1.16 require ( + github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 github.com/aliyun/aliyun-oss-go-sdk v2.1.6+incompatible + github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect github.com/casbin/casbin/v2 v2.11.0 github.com/casbin/gorm-adapter/v3 v3.0.2 github.com/dgrijalva/jwt-go v3.2.0+incompatible - github.com/flipped-aurora/gva-plug-email v0.0.0-20210823152517-a061eeea2d16 + github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect + github.com/flipped-aurora/ws v1.0.1 github.com/fsnotify/fsnotify v1.4.9 github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6 github.com/gin-gonic/gin v1.6.3 + github.com/go-ole/go-ole v1.2.4 // indirect + github.com/go-openapi/jsonreference v0.19.6 // indirect + github.com/go-openapi/spec v0.20.3 // indirect + github.com/go-openapi/swag v0.19.15 // indirect + github.com/go-playground/validator/v10 v10.3.0 // indirect github.com/go-redis/redis/v8 v8.11.0 github.com/go-sql-driver/mysql v1.5.0 github.com/gookit/color v1.3.1 + github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 // indirect github.com/jordan-wright/email v0.0.0-20200824153738-3f5bafa1cd84 + github.com/json-iterator/go v1.1.10 // indirect github.com/lestrrat-go/file-rotatelogs v2.3.0+incompatible + github.com/lestrrat-go/strftime v1.0.3 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/mitchellh/mapstructure v1.2.2 // indirect github.com/mojocn/base64Captcha v1.3.1 + github.com/pelletier/go-toml v1.6.0 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/qiniu/api.v7/v7 v7.4.1 github.com/robfig/cron/v3 v3.0.1 github.com/satori/go.uuid v1.2.0 github.com/shirou/gopsutil v3.21.1+incompatible + github.com/spf13/afero v1.2.2 // indirect + github.com/spf13/cast v1.3.1 // indirect + github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.7.0 github.com/swaggo/gin-swagger v1.3.0 github.com/swaggo/swag v1.7.0 + github.com/tebeka/strftime v0.1.3 // indirect github.com/tencentyun/cos-go-sdk-v5 v0.7.19 github.com/unrolled/secure v1.0.7 github.com/xuri/excelize/v2 v2.4.1 - go.uber.org/zap v1.10.0 + go.uber.org/zap v1.16.0 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c + golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect + golang.org/x/tools v0.1.5 // indirect + google.golang.org/protobuf v1.24.0 // indirect + gopkg.in/ini.v1 v1.55.0 // indirect gorm.io/driver/mysql v1.0.1 gorm.io/gorm v1.20.7 + nhooyr.io/websocket v1.8.6 ) diff --git a/server/initialize/plugin.go b/server/initialize/plugin.go index 02f6f1b9..75b2ca3d 100644 --- a/server/initialize/plugin.go +++ b/server/initialize/plugin.go @@ -2,6 +2,9 @@ package initialize import ( "github.com/flipped-aurora/gin-vue-admin/server/global" + "github.com/flipped-aurora/gin-vue-admin/server/plugin/ws" + "go.uber.org/zap" + //email "github.com/flipped-aurora/gva-plug-email" // 在线仓库模式 "github.com/flipped-aurora/gin-vue-admin/server/plugin/email" // 本地插件仓库地址模式 "github.com/flipped-aurora/gin-vue-admin/server/plugin/example_plugin" @@ -18,7 +21,8 @@ func PluginInit(group *gin.RouterGroup, Plugin ...plugin.Plugin) { func InstallPlugin(PublicGroup *gin.RouterGroup, PrivateGroup *gin.RouterGroup) { // 添加开放权限的插件 示例 - PluginInit(PublicGroup, example_plugin.ExamplePlugin) + PluginInit(PublicGroup, example_plugin.ExamplePlugin, ws.GenerateWs( + zap.L(), 100, ws.DefaultCheckMap())) // 添加跟角色挂钩权限的插件 示例 本地示例模式于在线仓库模式注意上方的import 可以自行切换 效果相同 PluginInit(PrivateGroup, email.CreateEmailPlug( diff --git a/server/plugin/ws/utils/utils.go b/server/plugin/ws/utils/utils.go new file mode 100644 index 00000000..85f91fe0 --- /dev/null +++ b/server/plugin/ws/utils/utils.go @@ -0,0 +1,52 @@ +package utils + +import ( + "github.com/flipped-aurora/gin-vue-admin/server/global" + systemReq "github.com/flipped-aurora/gin-vue-admin/server/model/system/request" + "github.com/gin-gonic/gin" + uuid "github.com/satori/go.uuid" +) + +// 从Gin的Context中获取从jwt解析出来的用户ID +func GetUserID(c *gin.Context) uint { + if claims, exists := c.Get("claims"); !exists { + global.GVA_LOG.Error("从Gin的Context中获取从jwt解析出来的用户ID失败, 请检查路由是否使用jwt中间件!") + return 0 + } else { + waitUse := claims.(*systemReq.CustomClaims) + return waitUse.ID + } +} + +// 从Gin的Context中获取从jwt解析出来的用户UUID +func GetUserUuid(c *gin.Context) uuid.UUID { + if claims, exists := c.Get("claims"); !exists { + global.GVA_LOG.Error("从Gin的Context中获取从jwt解析出来的用户UUID失败, 请检查路由是否使用jwt中间件!") + return uuid.UUID{} + } else { + waitUse := claims.(*systemReq.CustomClaims) + return waitUse.UUID + } +} + +// 从Gin的Context中获取从jwt解析出来的用户角色id +func GetUserAuthorityId(c *gin.Context) string { + if claims, exists := c.Get("claims"); !exists { + global.GVA_LOG.Error("从Gin的Context中获取从jwt解析出来的用户UUID失败, 请检查路由是否使用jwt中间件!") + return "" + } else { + waitUse := claims.(*systemReq.CustomClaims) + return waitUse.AuthorityId + } +} + +// 从Gin的Context中获取从jwt解析出来的用户角色id +func GetUserInfo(c *gin.Context) *systemReq.CustomClaims { + if claims, exists := c.Get("claims"); !exists { + global.GVA_LOG.Error("从Gin的Context中获取从jwt解析出来的用户UUID失败, 请检查路由是否使用jwt中间件!") + return nil + } else { + waitUse := claims.(*systemReq.CustomClaims) + return waitUse + } +} diff --git a/server/plugin/ws/ws.go b/server/plugin/ws/ws.go new file mode 100644 index 00000000..be63a2ff --- /dev/null +++ b/server/plugin/ws/ws.go @@ -0,0 +1,83 @@ +package ws + +import ( + "github.com/flipped-aurora/ws/core/biz" + "github.com/flipped-aurora/ws/core/data" + "github.com/gin-gonic/gin" + "go.uber.org/zap" + "nhooyr.io/websocket" +) + +type wsPlugin struct { + logger *zap.Logger // 日志输出对象 + manageBuf int64 // buffer + registeredMsgHandler map[int32]func(biz.IMessage) bool // 消息处理 + checkMap map[string]biz.CheckFunc // 用户校验 + + admin biz.IManage + adminCase *biz.AdminCase +} + +func DefaultRegisteredMsgHandler(admin biz.IManage, logger *zap.Logger) map[int32]func(biz.IMessage) bool { + return map[int32]func(msg biz.IMessage) bool{ + 1: func(msg biz.IMessage) bool { + // w.admin 里面找到注册客户端的方法 + client, ok := admin.FindClient(msg.GetTo()) + if !ok { + logger.Info("没有找到该用户") + return false + } + return client.SendMes(msg) + }, + } +} + +func DefaultCheckMap() map[string]biz.CheckFunc { + return map[string]biz.CheckFunc{ + "gva_ws": func(c interface{}) (string, bool) { + // 先断言是gin.content + cc, ok := c.(*gin.Context) + if !ok { + return "", false + } + token := cc.Query("jwt") + // 可以携带jwt + if len(token) == 0 { + return "", false + } + // 解析 jwt... + + return token, true + }, + } +} + +func (w *wsPlugin) Register(g *gin.RouterGroup) { + // gva_ws 为身份校验函数 + g.GET("/ws", w.adminCase.HandlerWS("gva_ws", &websocket.AcceptOptions{ + InsecureSkipVerify: true, + })) + g.POST("/sendMsg", w.adminCase.SendMsg("gva_ws")) + +} + +func (w *wsPlugin) RouterPath() string { + return "gva_ws" +} + +func GenerateWs(logger *zap.Logger, manageBuf int64, checkMap map[string]biz.CheckFunc) *wsPlugin { + m := data.NewManage(manageBuf) + t := data.NewTopic() + h := data.NewHandle() + admin := data.NewAdmin(m, t, h, logger) + for s, checkFunc := range checkMap { + admin.AddCheckFunc(s, checkFunc) + } + registeredMsgHandler := DefaultRegisteredMsgHandler(admin, logger) + + for key, handler := range registeredMsgHandler { + admin.RegisteredMsgHandler(key, handler) + } + return &wsPlugin{logger: logger, manageBuf: manageBuf, + registeredMsgHandler: registeredMsgHandler, checkMap: checkMap, admin: admin, adminCase: biz.NewAdmin(admin)} +} From 2f8a3e35d598323220f421136f83ffcb23527149 Mon Sep 17 00:00:00 2001 From: piexlmax Date: Wed, 1 Sep 2021 15:20:46 +0800 Subject: [PATCH 2/7] =?UTF-8?q?=E5=A2=9E=E5=8A=A0$CloseThisPage=E5=85=A8?= =?UTF-8?q?=E5=B1=80=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/core/gin-vue-admin.js | 6 ++---- web/src/core/global.js | 11 +++++++++++ .../view/layout/aside/historyComponent/history.vue | 1 - 3 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 web/src/core/global.js diff --git a/web/src/core/gin-vue-admin.js b/web/src/core/gin-vue-admin.js index e104f69a..fa2cb3e2 100644 --- a/web/src/core/gin-vue-admin.js +++ b/web/src/core/gin-vue-admin.js @@ -3,12 +3,10 @@ * * */ // 加载网站配置文件夹 -import config from './config' +import { register } from './global' export const run = function(app) { - app.config.globalProperties.$GIN_VUE_ADMIN = config - // app.use(uploader) - + register(app) console.log(` 欢迎使用 Gin-Vue-Admin 当前版本:V2.4.5 alpha diff --git a/web/src/core/global.js b/web/src/core/global.js new file mode 100644 index 00000000..988fd2d3 --- /dev/null +++ b/web/src/core/global.js @@ -0,0 +1,11 @@ +import config from './config' +import { emitter } from '@/utils/bus.js' + +const closeThisPage = () => { + emitter.emit('closeThisPage') +} + +export const register = (app) => { + app.config.globalProperties.$GIN_VUE_ADMIN = config + app.config.globalProperties.$CloseThisPage = closeThisPage +} diff --git a/web/src/view/layout/aside/historyComponent/history.vue b/web/src/view/layout/aside/historyComponent/history.vue index ee26c2f6..cd464d94 100644 --- a/web/src/view/layout/aside/historyComponent/history.vue +++ b/web/src/view/layout/aside/historyComponent/history.vue @@ -252,7 +252,6 @@ export default { }) }, removeTab(tab) { - console.log(tab) const index = this.historys.findIndex( item => getFmtString(item) === tab ) From d09aee0b82da3a224af8e6780a515e1ccf264a3c Mon Sep 17 00:00:00 2001 From: songzhibin97 <718428482@qq.com> Date: Wed, 1 Sep 2021 17:56:51 +0800 Subject: [PATCH 3/7] =?UTF-8?q?feat:=E6=96=B0=E5=A2=9E=E5=AE=9A=E6=97=B6?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=20=E5=88=A0=E9=99=A4jwt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/config.yaml | 1 + server/initialize/timer.go | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/server/config.yaml b/server/config.yaml index 66a4cf9e..8130f1ed 100644 --- a/server/config.yaml +++ b/server/config.yaml @@ -130,6 +130,7 @@ Timer: # interval: 时间间隔, 具体配置详看 time.ParseDuration() 中字符串表示 且不能为负数 # 2160h = 24 * 30 * 3 -> 三个月 { tableName: "sys_operation_records" , compareField: "created_at", interval: "2160h" }, + { tableName: "jwt_blacklists" , compareField: "created_at", interval: "168h" } #{ tableName: "log2" , compareField: "created_at", interval: "2160h" } ] diff --git a/server/initialize/timer.go b/server/initialize/timer.go index f65180b2..62c8185b 100644 --- a/server/initialize/timer.go +++ b/server/initialize/timer.go @@ -10,7 +10,7 @@ import ( func Timer() { if global.GVA_CONFIG.Timer.Start { - for _, detail := range global.GVA_CONFIG.Timer.Detail { + for i := range global.GVA_CONFIG.Timer.Detail { go func(detail config.Detail) { global.GVA_Timer.AddTaskByFunc("ClearDB", global.GVA_CONFIG.Timer.Spec, func() { err := utils.ClearTable(global.GVA_DB, detail.TableName, detail.CompareField, detail.Interval) @@ -18,7 +18,7 @@ func Timer() { fmt.Println("timer error:", err) } }) - }(detail) + }(global.GVA_CONFIG.Timer.Detail[i]) } } } From 8e1faa6d520f7b3d5d86140f9e0d7e3bfd440dc0 Mon Sep 17 00:00:00 2001 From: songzhibin97 <718428482@qq.com> Date: Wed, 1 Sep 2021 18:40:06 +0800 Subject: [PATCH 4/7] feat:black jwt --- server/core/viper.go | 11 ++++++++++ server/global/global.go | 3 +++ server/go.mod | 2 +- server/service/system/jwt_black_list.go | 28 +++++++++++++++++++------ 4 files changed, 37 insertions(+), 7 deletions(-) diff --git a/server/core/viper.go b/server/core/viper.go index b7c33a3e..bbcfd364 100644 --- a/server/core/viper.go +++ b/server/core/viper.go @@ -5,6 +5,11 @@ import ( "fmt" "os" "path/filepath" + "time" + + "github.com/flipped-aurora/gin-vue-admin/server/service/system" + + "github.com/songzhibin97/gkit/cache/local_cache" "github.com/flipped-aurora/gin-vue-admin/server/global" _ "github.com/flipped-aurora/gin-vue-admin/server/packfile" @@ -54,5 +59,11 @@ func Viper(path ...string) *viper.Viper { fmt.Println(err) } global.GVA_CONFIG.AutoCode.Root, _ = filepath.Abs("..") + global.BlackCache = local_cache.NewCache( + local_cache.SetDefaultExpire(time.Duration(global.GVA_CONFIG.JWT.ExpiresTime))) + // 从db加载jwt数据 + if global.GVA_DB != nil { + system.LoadAll() + } return v } diff --git a/server/global/global.go b/server/global/global.go index 58d7efd9..9093c505 100644 --- a/server/global/global.go +++ b/server/global/global.go @@ -2,6 +2,7 @@ package global import ( "github.com/flipped-aurora/gin-vue-admin/server/utils/timer" + "github.com/songzhibin97/gkit/cache/local_cache" "golang.org/x/sync/singleflight" @@ -23,4 +24,6 @@ var ( GVA_LOG *zap.Logger GVA_Timer timer.Timer = timer.NewTimerTask() GVA_Concurrency_Control = &singleflight.Group{} + + BlackCache local_cache.Cache ) diff --git a/server/go.mod b/server/go.mod index 055161d9..431182dd 100644 --- a/server/go.mod +++ b/server/go.mod @@ -36,6 +36,7 @@ require ( github.com/robfig/cron/v3 v3.0.1 github.com/satori/go.uuid v1.2.0 github.com/shirou/gopsutil v3.21.1+incompatible + github.com/songzhibin97/gkit v1.1.1 // indirect github.com/spf13/afero v1.2.2 // indirect github.com/spf13/cast v1.3.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect @@ -51,7 +52,6 @@ require ( golang.org/x/sync v0.0.0-20210220032951-036812b2e83c golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect golang.org/x/tools v0.1.5 // indirect - google.golang.org/protobuf v1.24.0 // indirect gopkg.in/ini.v1 v1.55.0 // indirect gorm.io/driver/mysql v1.0.1 gorm.io/gorm v1.20.7 diff --git a/server/service/system/jwt_black_list.go b/server/service/system/jwt_black_list.go index 83a094bf..a73c32be 100644 --- a/server/service/system/jwt_black_list.go +++ b/server/service/system/jwt_black_list.go @@ -2,13 +2,10 @@ package system import ( "context" - "errors" "time" "github.com/flipped-aurora/gin-vue-admin/server/global" "github.com/flipped-aurora/gin-vue-admin/server/model/system" - - "gorm.io/gorm" ) type JwtService struct { @@ -22,6 +19,11 @@ type JwtService struct { func (jwtService *JwtService) JsonInBlacklist(jwtList system.JwtBlacklist) (err error) { err = global.GVA_DB.Create(&jwtList).Error + if err != nil { + return + } + global.BlackCache.SetDefault(jwtList.Jwt, struct { + }{}) return } @@ -32,9 +34,11 @@ func (jwtService *JwtService) JsonInBlacklist(jwtList system.JwtBlacklist) (err //@return: bool func (jwtService *JwtService) IsBlacklist(jwt string) bool { - err := global.GVA_DB.Where("jwt = ?", jwt).First(&system.JwtBlacklist{}).Error - isNotFound := errors.Is(err, gorm.ErrRecordNotFound) - return !isNotFound + _, ok := global.BlackCache.Get(jwt) + return ok + //err := global.GVA_DB.Where("jwt = ?", jwt).First(&system.JwtBlacklist{}).Error + //isNotFound := errors.Is(err, gorm.ErrRecordNotFound) + //return !isNotFound } //@author: [piexlmax](https://github.com/piexlmax) @@ -60,3 +64,15 @@ func (jwtService *JwtService) SetRedisJWT(jwt string, userName string) (err erro err = global.GVA_REDIS.Set(context.Background(), userName, jwt, timer).Err() return err } + +func LoadAll() { + var data []string + err := global.GVA_DB.Find(&system.JwtBlacklist{}).Select("jwt").Find(&data).Error + if err != nil { + // 从db加载jwt数据 + for i := range data { + global.BlackCache.SetDefault(data[i], struct { + }{}) + } + } +} From c81293a0fed6e354c0caf996792878409e62e595 Mon Sep 17 00:00:00 2001 From: songzhibin97 <718428482@qq.com> Date: Wed, 1 Sep 2021 18:42:03 +0800 Subject: [PATCH 5/7] fix:go mod --- server/go.mod | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/server/go.mod b/server/go.mod index 431182dd..0fa3654b 100644 --- a/server/go.mod +++ b/server/go.mod @@ -3,7 +3,6 @@ module github.com/flipped-aurora/gin-vue-admin/server go 1.16 require ( - github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 github.com/aliyun/aliyun-oss-go-sdk v2.1.6+incompatible github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect @@ -14,7 +13,6 @@ require ( github.com/fsnotify/fsnotify v1.4.9 github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6 github.com/gin-gonic/gin v1.6.3 - github.com/go-ole/go-ole v1.2.4 // indirect github.com/go-openapi/jsonreference v0.19.6 // indirect github.com/go-openapi/spec v0.20.3 // indirect github.com/go-openapi/swag v0.19.15 // indirect @@ -31,12 +29,11 @@ require ( github.com/mitchellh/mapstructure v1.2.2 // indirect github.com/mojocn/base64Captcha v1.3.1 github.com/pelletier/go-toml v1.6.0 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/qiniu/api.v7/v7 v7.4.1 github.com/robfig/cron/v3 v3.0.1 github.com/satori/go.uuid v1.2.0 github.com/shirou/gopsutil v3.21.1+incompatible - github.com/songzhibin97/gkit v1.1.1 // indirect + github.com/songzhibin97/gkit v1.1.1 github.com/spf13/afero v1.2.2 // indirect github.com/spf13/cast v1.3.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect From c3f921d37ae14cb2a42e7aa7a9ba7b75447da992 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=92=8B=E5=90=89=E5=85=86?= <303176530@qq.com> Date: Wed, 1 Sep 2021 23:06:25 +0800 Subject: [PATCH 6/7] =?UTF-8?q?=E6=8F=90=E5=8D=87=E6=80=A7=E8=83=BD=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=89=8D=E7=AB=AFtab=E9=A1=B5=E9=9D=A2bug=20?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0ws=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/api/v1/system/sys_user.go | 5 +- server/go.mod | 2 + server/middleware/jwt.go | 100 ++---------------- server/utils/jwt.go | 71 +++++++++++++ web/package.json | 2 +- .../layout/aside/historyComponent/history.vue | 17 +-- web/src/view/layout/index.vue | 1 + 7 files changed, 97 insertions(+), 101 deletions(-) create mode 100644 server/utils/jwt.go diff --git a/server/api/v1/system/sys_user.go b/server/api/v1/system/sys_user.go index 1652523f..060d368c 100644 --- a/server/api/v1/system/sys_user.go +++ b/server/api/v1/system/sys_user.go @@ -5,7 +5,6 @@ import ( "time" "github.com/flipped-aurora/gin-vue-admin/server/global" - "github.com/flipped-aurora/gin-vue-admin/server/middleware" "github.com/flipped-aurora/gin-vue-admin/server/model/common/request" "github.com/flipped-aurora/gin-vue-admin/server/model/common/response" "github.com/flipped-aurora/gin-vue-admin/server/model/system" @@ -47,7 +46,7 @@ func (b *BaseApi) Login(c *gin.Context) { // 登录以后签发jwt func (b *BaseApi) tokenNext(c *gin.Context, user system.SysUser) { - j := &middleware.JWT{SigningKey: []byte(global.GVA_CONFIG.JWT.SigningKey)} // 唯一签名 + j := &utils.JWT{SigningKey: []byte(global.GVA_CONFIG.JWT.SigningKey)} // 唯一签名 claims := systemReq.CustomClaims{ UUID: user.UUID, ID: user.ID, @@ -210,7 +209,7 @@ func (b *BaseApi) SetUserAuthority(c *gin.Context) { response.FailWithMessage(err.Error(), c) } else { claims := utils.GetUserInfo(c) - j := &middleware.JWT{SigningKey: []byte(global.GVA_CONFIG.JWT.SigningKey)} // 唯一签名 + j := &utils.JWT{SigningKey: []byte(global.GVA_CONFIG.JWT.SigningKey)} // 唯一签名 claims.AuthorityId = sua.AuthorityId if token, err := j.CreateToken(*claims); err != nil { global.GVA_LOG.Error("修改失败!", zap.Any("err", err)) diff --git a/server/go.mod b/server/go.mod index e9aab535..58369fe1 100644 --- a/server/go.mod +++ b/server/go.mod @@ -9,6 +9,7 @@ require ( github.com/casbin/gorm-adapter/v3 v3.0.2 github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/flipped-aurora/gva-plugins v0.0.0-20210828060501-fc8b729b9a4a + github.com/flipped-aurora/ws v1.0.2 github.com/fsnotify/fsnotify v1.4.9 github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6 github.com/gin-gonic/gin v1.6.3 @@ -22,6 +23,7 @@ require ( github.com/robfig/cron/v3 v3.0.1 github.com/satori/go.uuid v1.2.0 github.com/shirou/gopsutil v3.21.1+incompatible + github.com/songzhibin97/gkit v1.1.1 github.com/spf13/viper v1.7.0 github.com/swaggo/gin-swagger v1.3.0 github.com/swaggo/swag v1.7.0 diff --git a/server/middleware/jwt.go b/server/middleware/jwt.go index 3eb701ad..adf82791 100644 --- a/server/middleware/jwt.go +++ b/server/middleware/jwt.go @@ -1,17 +1,15 @@ package middleware import ( - "errors" + "github.com/flipped-aurora/gin-vue-admin/server/utils" "strconv" "time" "github.com/flipped-aurora/gin-vue-admin/server/global" "github.com/flipped-aurora/gin-vue-admin/server/model/common/response" "github.com/flipped-aurora/gin-vue-admin/server/model/system" - "github.com/flipped-aurora/gin-vue-admin/server/model/system/request" "github.com/flipped-aurora/gin-vue-admin/server/service" - "github.com/dgrijalva/jwt-go" "github.com/gin-gonic/gin" "go.uber.org/zap" ) @@ -32,11 +30,11 @@ func JWTAuth() gin.HandlerFunc { c.Abort() return } - j := NewJWT() + j := utils.NewJWT() // parseToken 解析token包含的信息 claims, err := j.ParseToken(token) if err != nil { - if err == TokenExpired { + if err == utils.TokenExpired { response.FailWithDetailed(gin.H{"reload": true}, "授权已过期", c) c.Abort() return @@ -45,11 +43,12 @@ func JWTAuth() gin.HandlerFunc { c.Abort() return } - if err, _ = userService.FindUserByUuid(claims.UUID.String()); err != nil { - _ = jwtService.JsonInBlacklist(system.JwtBlacklist{Jwt: token}) - response.FailWithDetailed(gin.H{"reload": true}, err.Error(), c) - c.Abort() - } + // 用户被删除的逻辑 需要优化 此处比较消耗性能 如果需要 请自行打开 + //if err, _ = userService.FindUserByUuid(claims.UUID.String()); err != nil { + // _ = jwtService.JsonInBlacklist(system.JwtBlacklist{Jwt: token}) + // response.FailWithDetailed(gin.H{"reload": true}, err.Error(), c) + // c.Abort() + //} if claims.ExpiresAt-time.Now().Unix() < claims.BufferTime { claims.ExpiresAt = time.Now().Unix() + global.GVA_CONFIG.JWT.ExpiresTime newToken, _ := j.CreateTokenByOldToken(token, *claims) @@ -72,84 +71,3 @@ func JWTAuth() gin.HandlerFunc { } } -type JWT struct { - SigningKey []byte -} - -var ( - TokenExpired = errors.New("Token is expired") - TokenNotValidYet = errors.New("Token not active yet") - TokenMalformed = errors.New("That's not even a token") - TokenInvalid = errors.New("Couldn't handle this token:") -) - -func NewJWT() *JWT { - return &JWT{ - []byte(global.GVA_CONFIG.JWT.SigningKey), - } -} - -// 创建一个token -func (j *JWT) CreateToken(claims request.CustomClaims) (string, error) { - token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) - return token.SignedString(j.SigningKey) -} - -// CreateTokenByOldToken 旧token 换新token 使用归并回源避免并发问题 -func (j *JWT) CreateTokenByOldToken(oldToken string, claims request.CustomClaims) (string, error) { - v, err, _ := global.GVA_Concurrency_Control.Do("JWT:"+oldToken, func() (interface{}, error) { - return j.CreateToken(claims) - }) - return v.(string), err -} - -// 解析 token -func (j *JWT) ParseToken(tokenString string) (*request.CustomClaims, error) { - token, err := jwt.ParseWithClaims(tokenString, &request.CustomClaims{}, func(token *jwt.Token) (i interface{}, e error) { - return j.SigningKey, nil - }) - if err != nil { - if ve, ok := err.(*jwt.ValidationError); ok { - if ve.Errors&jwt.ValidationErrorMalformed != 0 { - return nil, TokenMalformed - } else if ve.Errors&jwt.ValidationErrorExpired != 0 { - // Token is expired - return nil, TokenExpired - } else if ve.Errors&jwt.ValidationErrorNotValidYet != 0 { - return nil, TokenNotValidYet - } else { - return nil, TokenInvalid - } - } - } - if token != nil { - if claims, ok := token.Claims.(*request.CustomClaims); ok && token.Valid { - return claims, nil - } - return nil, TokenInvalid - - } else { - return nil, TokenInvalid - - } - -} - -// 更新token -//func (j *JWT) RefreshToken(tokenString string) (string, error) { -// jwt.TimeFunc = func() time.Time { -// return time.Unix(0, 0) -// } -// token, err := jwt.ParseWithClaims(tokenString, &request.CustomClaims{}, func(token *jwt.Token) (interface{}, error) { -// return j.SigningKey, nil -// }) -// if err != nil { -// return "", err -// } -// if claims, ok := token.Claims.(*request.CustomClaims); ok && token.Valid { -// jwt.TimeFunc = time.Now -// claims.StandardClaims.ExpiresAt = time.Now().Unix() + 60*60*24*7 -// return j.CreateToken(*claims) -// } -// return "", TokenInvalid -//} diff --git a/server/utils/jwt.go b/server/utils/jwt.go new file mode 100644 index 00000000..a8d43d23 --- /dev/null +++ b/server/utils/jwt.go @@ -0,0 +1,71 @@ +package utils + +import ( + "errors" + "github.com/dgrijalva/jwt-go" + "github.com/flipped-aurora/gin-vue-admin/server/global" + "github.com/flipped-aurora/gin-vue-admin/server/model/system/request" +) + +type JWT struct { + SigningKey []byte +} + +var ( + TokenExpired = errors.New("Token is expired") + TokenNotValidYet = errors.New("Token not active yet") + TokenMalformed = errors.New("That's not even a token") + TokenInvalid = errors.New("Couldn't handle this token:") +) + +func NewJWT() *JWT { + return &JWT{ + []byte(global.GVA_CONFIG.JWT.SigningKey), + } +} + +// 创建一个token +func (j *JWT) CreateToken(claims request.CustomClaims) (string, error) { + token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) + return token.SignedString(j.SigningKey) +} + +// CreateTokenByOldToken 旧token 换新token 使用归并回源避免并发问题 +func (j *JWT) CreateTokenByOldToken(oldToken string, claims request.CustomClaims) (string, error) { + v, err, _ := global.GVA_Concurrency_Control.Do("JWT:"+oldToken, func() (interface{}, error) { + return j.CreateToken(claims) + }) + return v.(string), err +} + +// 解析 token +func (j *JWT) ParseToken(tokenString string) (*request.CustomClaims, error) { + token, err := jwt.ParseWithClaims(tokenString, &request.CustomClaims{}, func(token *jwt.Token) (i interface{}, e error) { + return j.SigningKey, nil + }) + if err != nil { + if ve, ok := err.(*jwt.ValidationError); ok { + if ve.Errors&jwt.ValidationErrorMalformed != 0 { + return nil, TokenMalformed + } else if ve.Errors&jwt.ValidationErrorExpired != 0 { + // Token is expired + return nil, TokenExpired + } else if ve.Errors&jwt.ValidationErrorNotValidYet != 0 { + return nil, TokenNotValidYet + } else { + return nil, TokenInvalid + } + } + } + if token != nil { + if claims, ok := token.Claims.(*request.CustomClaims); ok && token.Valid { + return claims, nil + } + return nil, TokenInvalid + + } else { + return nil, TokenInvalid + + } + +} \ No newline at end of file diff --git a/web/package.json b/web/package.json index fc754b2a..a61f68f4 100644 --- a/web/package.json +++ b/web/package.json @@ -1,6 +1,6 @@ { "name": "gin-vue-admin", - "version": "0.1.0", + "version": "2.3.5 ", "private": true, "scripts": { "serve": "node openDocument.js && vue-cli-service serve", diff --git a/web/src/view/layout/aside/historyComponent/history.vue b/web/src/view/layout/aside/historyComponent/history.vue index cd464d94..6dfc2dcc 100644 --- a/web/src/view/layout/aside/historyComponent/history.vue +++ b/web/src/view/layout/aside/historyComponent/history.vue @@ -74,6 +74,9 @@ export default { } }, $route(to, now) { + if (to.name === 'Login') { + return + } this.historys = this.historys.filter(item => !item.meta.closeTab) this.setTab(to) sessionStorage.setItem('historys', JSON.stringify(this.historys)) @@ -84,6 +87,14 @@ export default { } }, created() { + // 全局监听 关闭当前页面函数 + emitter.on('closeThisPage', () => { + this.removeTab(this.name(this.$route)) + }) + // 全局监听 关闭所有页面函数 + emitter.on('closeAllPage', () => { + this.closeAll() + }) emitter.on('mobile', isMobile => { this.isMobile = isMobile }) @@ -109,12 +120,6 @@ export default { } this.setTab(this.$route) }, - mounted() { - // 全局监听 关闭当前页面函数 - emitter.on('closeThisPage', () => { - this.removeTab(this.name(this.$route)) - }) - }, beforeDestroy() { emitter.off('collapse') emitter.off('mobile') diff --git a/web/src/view/layout/index.vue b/web/src/view/layout/index.vue index 8eef7cd8..26684c5f 100644 --- a/web/src/view/layout/index.vue +++ b/web/src/view/layout/index.vue @@ -212,6 +212,7 @@ export default { authorityId: id }) if (res.code === 0) { + emitter.emit('closeAllPage') window.location.reload() } }, From 811d1c9414ce93afe5bcfee57221a838ff99e333 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=92=8B=E5=90=89=E5=85=86?= <303176530@qq.com> Date: Wed, 1 Sep 2021 23:09:31 +0800 Subject: [PATCH 7/7] =?UTF-8?q?=E6=B8=85=E9=99=A4packagebug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/package.json b/web/package.json index a61f68f4..8dc78c62 100644 --- a/web/package.json +++ b/web/package.json @@ -1,6 +1,6 @@ { "name": "gin-vue-admin", - "version": "2.3.5 ", + "version": "2.3.5", "private": true, "scripts": { "serve": "node openDocument.js && vue-cli-service serve",