mirror of
				https://gitee.com/dromara/mayfly-go
				synced 2025-11-04 00:10:25 +08:00 
			
		
		
		
	feat: 支持redis缓存权限等信息
This commit is contained in:
		@@ -24,9 +24,15 @@ mysql:
 | 
				
			|||||||
  db-name: mayfly-go
 | 
					  db-name: mayfly-go
 | 
				
			||||||
  config: charset=utf8&loc=Local&parseTime=true
 | 
					  config: charset=utf8&loc=Local&parseTime=true
 | 
				
			||||||
  max-idle-conns: 5
 | 
					  max-idle-conns: 5
 | 
				
			||||||
 | 
					# 若同时部署多台机器,则需要配置redis信息用于缓存权限码、验证码、公私钥等
 | 
				
			||||||
 | 
					# redis:
 | 
				
			||||||
 | 
					#   host: localhost
 | 
				
			||||||
 | 
					#   port: 6379
 | 
				
			||||||
 | 
					#   passsord: 
 | 
				
			||||||
 | 
					#   db: 0
 | 
				
			||||||
log:
 | 
					log:
 | 
				
			||||||
   # 日志等级, trace, debug, info, warn, error, fatal
 | 
					   # 日志等级, trace, debug, info, warn, error, fatal
 | 
				
			||||||
  level: info
 | 
					  level: info
 | 
				
			||||||
  file:
 | 
					  # file:
 | 
				
			||||||
    path: ./
 | 
					  #   path: ./
 | 
				
			||||||
    name: mayfly-go.log
 | 
					  #   name: mayfly-go.log
 | 
				
			||||||
@@ -3,10 +3,10 @@ module mayfly-go
 | 
				
			|||||||
go 1.19
 | 
					go 1.19
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require (
 | 
					require (
 | 
				
			||||||
	github.com/gin-gonic/gin v1.8.1
 | 
						github.com/gin-gonic/gin v1.8.2
 | 
				
			||||||
	github.com/go-redis/redis/v8 v8.11.5
 | 
						github.com/go-redis/redis/v8 v8.11.5
 | 
				
			||||||
	github.com/go-sql-driver/mysql v1.7.0
 | 
						github.com/go-sql-driver/mysql v1.7.0
 | 
				
			||||||
	github.com/golang-jwt/jwt/v4 v4.4.2
 | 
						github.com/golang-jwt/jwt/v4 v4.4.3
 | 
				
			||||||
	github.com/gorilla/websocket v1.5.0
 | 
						github.com/gorilla/websocket v1.5.0
 | 
				
			||||||
	github.com/lib/pq v1.10.6
 | 
						github.com/lib/pq v1.10.6
 | 
				
			||||||
	github.com/mojocn/base64Captcha v1.3.5 // 验证码
 | 
						github.com/mojocn/base64Captcha v1.3.5 // 验证码
 | 
				
			||||||
@@ -28,8 +28,8 @@ require (
 | 
				
			|||||||
	github.com/gin-contrib/sse v0.1.0 // indirect
 | 
						github.com/gin-contrib/sse v0.1.0 // indirect
 | 
				
			||||||
	github.com/go-playground/locales v0.14.0 // indirect
 | 
						github.com/go-playground/locales v0.14.0 // indirect
 | 
				
			||||||
	github.com/go-playground/universal-translator v0.18.0 // indirect
 | 
						github.com/go-playground/universal-translator v0.18.0 // indirect
 | 
				
			||||||
	github.com/go-playground/validator/v10 v10.10.1 // indirect
 | 
						github.com/go-playground/validator/v10 v10.11.1 // indirect
 | 
				
			||||||
	github.com/goccy/go-json v0.9.7 // indirect
 | 
						github.com/goccy/go-json v0.9.11 // indirect
 | 
				
			||||||
	github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
 | 
						github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
 | 
				
			||||||
	github.com/golang/snappy v0.0.1 // indirect
 | 
						github.com/golang/snappy v0.0.1 // indirect
 | 
				
			||||||
	github.com/jinzhu/inflection v1.0.0 // indirect
 | 
						github.com/jinzhu/inflection v1.0.0 // indirect
 | 
				
			||||||
@@ -38,11 +38,11 @@ require (
 | 
				
			|||||||
	github.com/klauspost/compress v1.13.6 // indirect
 | 
						github.com/klauspost/compress v1.13.6 // indirect
 | 
				
			||||||
	github.com/kr/fs v0.1.0 // indirect
 | 
						github.com/kr/fs v0.1.0 // indirect
 | 
				
			||||||
	github.com/leodido/go-urn v1.2.1 // indirect
 | 
						github.com/leodido/go-urn v1.2.1 // indirect
 | 
				
			||||||
	github.com/mattn/go-isatty v0.0.14 // indirect
 | 
						github.com/mattn/go-isatty v0.0.16 // indirect
 | 
				
			||||||
	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 | 
						github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 | 
				
			||||||
	github.com/modern-go/reflect2 v1.0.2 // indirect
 | 
						github.com/modern-go/reflect2 v1.0.2 // indirect
 | 
				
			||||||
	github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
 | 
						github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
 | 
				
			||||||
	github.com/pelletier/go-toml/v2 v2.0.1 // indirect
 | 
						github.com/pelletier/go-toml/v2 v2.0.6 // indirect
 | 
				
			||||||
	github.com/pkg/errors v0.9.1 // indirect
 | 
						github.com/pkg/errors v0.9.1 // indirect
 | 
				
			||||||
	github.com/ugorji/go/codec v1.2.7 // indirect
 | 
						github.com/ugorji/go/codec v1.2.7 // indirect
 | 
				
			||||||
	github.com/xdg-go/pbkdf2 v1.0.0 // indirect
 | 
						github.com/xdg-go/pbkdf2 v1.0.0 // indirect
 | 
				
			||||||
@@ -50,11 +50,11 @@ require (
 | 
				
			|||||||
	github.com/xdg-go/stringprep v1.0.3 // indirect
 | 
						github.com/xdg-go/stringprep v1.0.3 // indirect
 | 
				
			||||||
	github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
 | 
						github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
 | 
				
			||||||
	golang.org/x/image v0.0.0-20220302094943-723b81ca9867 // indirect
 | 
						golang.org/x/image v0.0.0-20220302094943-723b81ca9867 // indirect
 | 
				
			||||||
	golang.org/x/net v0.3.0 // indirect
 | 
						golang.org/x/net v0.4.0 // indirect
 | 
				
			||||||
	golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
 | 
						golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
 | 
				
			||||||
	golang.org/x/sys v0.3.0 // indirect
 | 
						golang.org/x/sys v0.3.0 // indirect
 | 
				
			||||||
	golang.org/x/text v0.5.0 // indirect
 | 
						golang.org/x/text v0.5.0 // indirect
 | 
				
			||||||
	golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
 | 
						golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
 | 
				
			||||||
	google.golang.org/protobuf v1.28.0 // indirect
 | 
						google.golang.org/protobuf v1.28.1 // indirect
 | 
				
			||||||
	gopkg.in/yaml.v2 v2.4.0 // indirect
 | 
						gopkg.in/yaml.v2 v2.4.0 // indirect
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										34
									
								
								server/pkg/cache/str_cache.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								server/pkg/cache/str_cache.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					package cache
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "mayfly-go/pkg/rediscli"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var strCache map[string]string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 如果系统有设置redis信息,则从redis获取,否则本机内存获取
 | 
				
			||||||
 | 
					func GetStr(key string) string {
 | 
				
			||||||
 | 
						if rediscli.GetCli() == nil {
 | 
				
			||||||
 | 
							checkStrCache()
 | 
				
			||||||
 | 
							return strCache[key]
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						res, err := rediscli.Get(key)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return ""
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return res
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 如果系统有设置redis信息,则使用redis存,否则存于本机内存
 | 
				
			||||||
 | 
					func SetStr(key, value string) {
 | 
				
			||||||
 | 
						if rediscli.GetCli() == nil {
 | 
				
			||||||
 | 
							checkStrCache()
 | 
				
			||||||
 | 
							strCache[key] = value
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						rediscli.Set(key, value, 0)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func checkStrCache() {
 | 
				
			||||||
 | 
						if strCache == nil {
 | 
				
			||||||
 | 
							strCache = make(map[string]string)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -2,15 +2,25 @@ package captcha
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"mayfly-go/pkg/biz"
 | 
						"mayfly-go/pkg/biz"
 | 
				
			||||||
 | 
						"mayfly-go/pkg/rediscli"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/mojocn/base64Captcha"
 | 
						"github.com/mojocn/base64Captcha"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var store = base64Captcha.DefaultMemStore
 | 
					var store base64Captcha.Store
 | 
				
			||||||
var driver base64Captcha.Driver = base64Captcha.DefaultDriverDigit
 | 
					var driver base64Captcha.Driver = base64Captcha.DefaultDriverDigit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 生成验证码
 | 
					// 生成验证码
 | 
				
			||||||
func Generate() (string, string) {
 | 
					func Generate() (string, string) {
 | 
				
			||||||
 | 
						if store == nil {
 | 
				
			||||||
 | 
							if rediscli.GetCli() != nil {
 | 
				
			||||||
 | 
								store = new(RedisStore)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								store = base64Captcha.DefaultMemStore
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	c := base64Captcha.NewCaptcha(driver, store)
 | 
						c := base64Captcha.NewCaptcha(driver, store)
 | 
				
			||||||
	// 获取
 | 
						// 获取
 | 
				
			||||||
	id, b64s, err := c.Generate()
 | 
						id, b64s, err := c.Generate()
 | 
				
			||||||
@@ -26,3 +36,34 @@ func Verify(id string, val string) bool {
 | 
				
			|||||||
	// 同时清理掉这个图片
 | 
						// 同时清理掉这个图片
 | 
				
			||||||
	return store.Verify(id, val, true)
 | 
						return store.Verify(id, val, true)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type RedisStore struct {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const CAPTCHA = "mayfly:captcha:"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 实现设置captcha的方法
 | 
				
			||||||
 | 
					func (r RedisStore) Set(id string, value string) error {
 | 
				
			||||||
 | 
						//time.Minute*2:有效时间2分钟
 | 
				
			||||||
 | 
						rediscli.Set(CAPTCHA+id, value, time.Minute*2)
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 实现获取captcha的方法
 | 
				
			||||||
 | 
					func (r RedisStore) Get(id string, clear bool) string {
 | 
				
			||||||
 | 
						key := CAPTCHA + id
 | 
				
			||||||
 | 
						val, err := rediscli.Get(key)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return ""
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if clear {
 | 
				
			||||||
 | 
							//clear为true,验证通过,删除这个验证码
 | 
				
			||||||
 | 
							rediscli.Del(key)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return val
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 实现验证captcha的方法
 | 
				
			||||||
 | 
					func (r RedisStore) Verify(id, answer string, clear bool) bool {
 | 
				
			||||||
 | 
						return r.Get(id, clear) == answer
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -40,8 +40,8 @@ type Config struct {
 | 
				
			|||||||
	Server *Server `yaml:"server"`
 | 
						Server *Server `yaml:"server"`
 | 
				
			||||||
	Jwt    *Jwt    `yaml:"jwt"`
 | 
						Jwt    *Jwt    `yaml:"jwt"`
 | 
				
			||||||
	Aes    *Aes    `yaml:"aes"`
 | 
						Aes    *Aes    `yaml:"aes"`
 | 
				
			||||||
	Redis  *Redis  `yaml:"redis"`
 | 
					 | 
				
			||||||
	Mysql  *Mysql  `yaml:"mysql"`
 | 
						Mysql  *Mysql  `yaml:"mysql"`
 | 
				
			||||||
 | 
						Redis  *Redis  `yaml:"redis"`
 | 
				
			||||||
	Log    *Log    `yaml:"log"`
 | 
						Log    *Log    `yaml:"log"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +1,13 @@
 | 
				
			|||||||
package ctx
 | 
					package ctx
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"mayfly-go/pkg/biz"
 | 
						"mayfly-go/pkg/biz"
 | 
				
			||||||
	"mayfly-go/pkg/cache"
 | 
						"mayfly-go/pkg/cache"
 | 
				
			||||||
	"mayfly-go/pkg/config"
 | 
						"mayfly-go/pkg/config"
 | 
				
			||||||
 | 
						"mayfly-go/pkg/rediscli"
 | 
				
			||||||
 | 
						"mayfly-go/pkg/utils"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -22,6 +25,62 @@ func (p *Permission) WithNeedToken(needToken bool) *Permission {
 | 
				
			|||||||
	return p
 | 
						return p
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var (
 | 
				
			||||||
 | 
						permissionCodeRegistry PermissionCodeRegistry
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func PermissionHandler(rc *ReqCtx) error {
 | 
				
			||||||
 | 
						if permissionCodeRegistry == nil {
 | 
				
			||||||
 | 
							if rediscli.GetCli() == nil {
 | 
				
			||||||
 | 
								permissionCodeRegistry = new(DefaultPermissionCodeRegistry)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								permissionCodeRegistry = new(RedisPermissionCodeRegistry)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						permission := rc.RequiredPermission
 | 
				
			||||||
 | 
						// 如果需要的权限信息不为空,并且不需要token,则不返回错误,继续后续逻辑
 | 
				
			||||||
 | 
						if permission != nil && !permission.NeedToken {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						tokenStr := rc.GinCtx.Request.Header.Get("Authorization")
 | 
				
			||||||
 | 
						// header不存在则从查询参数token中获取
 | 
				
			||||||
 | 
						if tokenStr == "" {
 | 
				
			||||||
 | 
							tokenStr = rc.GinCtx.Query("token")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if tokenStr == "" {
 | 
				
			||||||
 | 
							return biz.PermissionErr
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						loginAccount, err := ParseToken(tokenStr)
 | 
				
			||||||
 | 
						if err != nil || loginAccount == nil {
 | 
				
			||||||
 | 
							return biz.PermissionErr
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// 权限不为nil,并且permission code不为空,则校验是否有权限code
 | 
				
			||||||
 | 
						if permission != nil && permission.Code != "" {
 | 
				
			||||||
 | 
							if !permissionCodeRegistry.HasCode(loginAccount.Id, permission.Code) {
 | 
				
			||||||
 | 
								return biz.PermissionErr
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rc.LoginAccount = loginAccount
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 保存用户权限code
 | 
				
			||||||
 | 
					func SavePermissionCodes(userId uint64, codes []string) {
 | 
				
			||||||
 | 
						permissionCodeRegistry.SaveCodes(userId, codes)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 删除用户权限code
 | 
				
			||||||
 | 
					func DeletePermissionCodes(userId uint64) {
 | 
				
			||||||
 | 
						permissionCodeRegistry.Remove(userId)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 设置权限code注册器
 | 
				
			||||||
 | 
					func SetPermissionCodeRegistery(pcr PermissionCodeRegistry) {
 | 
				
			||||||
 | 
						permissionCodeRegistry = pcr
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type PermissionCodeRegistry interface {
 | 
					type PermissionCodeRegistry interface {
 | 
				
			||||||
	// 保存用户权限code
 | 
						// 保存用户权限code
 | 
				
			||||||
	SaveCodes(userId uint64, codes []string)
 | 
						SaveCodes(userId uint64, codes []string)
 | 
				
			||||||
@@ -63,51 +122,29 @@ func (r *DefaultPermissionCodeRegistry) Remove(userId uint64) {
 | 
				
			|||||||
	r.cache.Delete(fmt.Sprintf("%v", userId))
 | 
						r.cache.Delete(fmt.Sprintf("%v", userId))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 保存用户权限code
 | 
					type RedisPermissionCodeRegistry struct {
 | 
				
			||||||
func SavePermissionCodes(userId uint64, codes []string) {
 | 
					 | 
				
			||||||
	permissionCodeRegistry.SaveCodes(userId, codes)
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 删除用户权限code
 | 
					func (r *RedisPermissionCodeRegistry) SaveCodes(userId uint64, codes []string) {
 | 
				
			||||||
func DeletePermissionCodes(userId uint64) {
 | 
						rediscli.Set(fmt.Sprintf("mayfly:%v:codes", userId), utils.ToString(codes), time.Minute*time.Duration(config.Conf.Jwt.ExpireTime))
 | 
				
			||||||
	permissionCodeRegistry.Remove(userId)
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 设置权限code注册器
 | 
					func (r *RedisPermissionCodeRegistry) HasCode(userId uint64, code string) bool {
 | 
				
			||||||
func SetPermissionCodeRegistery(pcr PermissionCodeRegistry) {
 | 
						str, err := rediscli.Get(fmt.Sprintf("mayfly:%v:codes", userId))
 | 
				
			||||||
	permissionCodeRegistry = pcr
 | 
						if err != nil || str == "" {
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
						var codes []string
 | 
				
			||||||
	permissionCodeRegistry PermissionCodeRegistry = &DefaultPermissionCodeRegistry{}
 | 
						_ = json.Unmarshal([]byte(str), &codes)
 | 
				
			||||||
	// permissionError                               = biz.NewBizErrCode(biz.TokenErrorCode, biz.TokenErrorMsg)
 | 
						for _, v := range codes {
 | 
				
			||||||
)
 | 
							if v == code {
 | 
				
			||||||
 | 
								return true
 | 
				
			||||||
func PermissionHandler(rc *ReqCtx) error {
 | 
					 | 
				
			||||||
	permission := rc.RequiredPermission
 | 
					 | 
				
			||||||
	// 如果需要的权限信息不为空,并且不需要token,则不返回错误,继续后续逻辑
 | 
					 | 
				
			||||||
	if permission != nil && !permission.NeedToken {
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	tokenStr := rc.GinCtx.Request.Header.Get("Authorization")
 | 
					 | 
				
			||||||
	// header不存在则从查询参数token中获取
 | 
					 | 
				
			||||||
	if tokenStr == "" {
 | 
					 | 
				
			||||||
		tokenStr = rc.GinCtx.Query("token")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if tokenStr == "" {
 | 
					 | 
				
			||||||
		return biz.PermissionErr
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	loginAccount, err := ParseToken(tokenStr)
 | 
					 | 
				
			||||||
	if err != nil || loginAccount == nil {
 | 
					 | 
				
			||||||
		return biz.PermissionErr
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// 权限不为nil,并且permission code不为空,则校验是否有权限code
 | 
					 | 
				
			||||||
	if permission != nil && permission.Code != "" {
 | 
					 | 
				
			||||||
		if !permissionCodeRegistry.HasCode(loginAccount.Id, permission.Code) {
 | 
					 | 
				
			||||||
			return biz.PermissionErr
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rc.LoginAccount = loginAccount
 | 
					func (r *RedisPermissionCodeRegistry) Remove(userId uint64) {
 | 
				
			||||||
	return nil
 | 
						rediscli.Del(fmt.Sprintf("mayfly:%v:codes", userId))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,6 @@
 | 
				
			|||||||
package global
 | 
					package global
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"github.com/go-redis/redis/v8"
 | 
					 | 
				
			||||||
	"github.com/sirupsen/logrus"
 | 
						"github.com/sirupsen/logrus"
 | 
				
			||||||
	"gorm.io/gorm"
 | 
						"gorm.io/gorm"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -9,5 +8,4 @@ import (
 | 
				
			|||||||
var (
 | 
					var (
 | 
				
			||||||
	Log *logrus.Logger // 日志
 | 
						Log *logrus.Logger // 日志
 | 
				
			||||||
	Db  *gorm.DB       // gorm
 | 
						Db  *gorm.DB       // gorm
 | 
				
			||||||
	RedisCli *redis.Client  // redis
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,6 @@ package rediscli
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/go-redis/redis/v8"
 | 
						"github.com/go-redis/redis/v8"
 | 
				
			||||||
@@ -19,17 +18,8 @@ func GetCli() *redis.Client {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// get key value
 | 
					// get key value
 | 
				
			||||||
func Get(key string) string {
 | 
					func Get(key string) (string, error) {
 | 
				
			||||||
	val, err := cli.Get(context.TODO(), key).Result()
 | 
						return cli.Get(context.TODO(), key).Result()
 | 
				
			||||||
	switch {
 | 
					 | 
				
			||||||
	case err == redis.Nil:
 | 
					 | 
				
			||||||
		fmt.Println("key does not exist")
 | 
					 | 
				
			||||||
	case err != nil:
 | 
					 | 
				
			||||||
		fmt.Println("Get failed", err)
 | 
					 | 
				
			||||||
	case val == "":
 | 
					 | 
				
			||||||
		fmt.Println("value is empty")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return val
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// set key value
 | 
					// set key value
 | 
				
			||||||
@@ -37,6 +27,10 @@ func Set(key string, val string, expiration time.Duration) {
 | 
				
			|||||||
	cli.Set(context.TODO(), key, val, expiration)
 | 
						cli.Set(context.TODO(), key, val, expiration)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func Del(key string) {
 | 
				
			||||||
 | 
						cli.Del(context.TODO(), key)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func HSet(key string, field string, val interface{}) {
 | 
					func HSet(key string, field string, val interface{}) {
 | 
				
			||||||
	cli.HSet(context.TODO(), key, field, val)
 | 
						cli.HSet(context.TODO(), key, field, val)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,19 +5,20 @@ import (
 | 
				
			|||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"mayfly-go/pkg/config"
 | 
						"mayfly-go/pkg/config"
 | 
				
			||||||
	"mayfly-go/pkg/global"
 | 
						"mayfly-go/pkg/global"
 | 
				
			||||||
 | 
						"mayfly-go/pkg/rediscli"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/go-redis/redis/v8"
 | 
						"github.com/go-redis/redis/v8"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func InitRedis() {
 | 
					func initRedis() {
 | 
				
			||||||
	global.RedisCli = ConnRedis()
 | 
						rediscli.SetCli(connRedis())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func ConnRedis() *redis.Client {
 | 
					func connRedis() *redis.Client {
 | 
				
			||||||
	// 设置redis客户端
 | 
						// 设置redis客户端
 | 
				
			||||||
	redisConf := config.Conf.Redis
 | 
						redisConf := config.Conf.Redis
 | 
				
			||||||
	if redisConf == nil {
 | 
						if redisConf == nil {
 | 
				
			||||||
		global.Log.Panic("未找到redis配置信息")
 | 
							// global.Log.Panic("未找到redis配置信息")
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	global.Log.Infof("连接redis [%s:%d]", redisConf.Host, redisConf.Port)
 | 
						global.Log.Infof("连接redis [%s:%d]", redisConf.Host, redisConf.Port)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,6 +18,8 @@ func RunWebServer() {
 | 
				
			|||||||
	printBanner()
 | 
						printBanner()
 | 
				
			||||||
	// 初始化并赋值数据库全局变量
 | 
						// 初始化并赋值数据库全局变量
 | 
				
			||||||
	initDb()
 | 
						initDb()
 | 
				
			||||||
 | 
						// 有配置redis信息,则初始化redis。多台机器部署需要使用redis存储验证码、权限、公私钥等
 | 
				
			||||||
 | 
						initRedis()
 | 
				
			||||||
	// 运行web服务
 | 
						// 运行web服务
 | 
				
			||||||
	runWebServer()
 | 
						runWebServer()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,6 +12,7 @@ import (
 | 
				
			|||||||
	"encoding/hex"
 | 
						"encoding/hex"
 | 
				
			||||||
	"encoding/pem"
 | 
						"encoding/pem"
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
 | 
						"mayfly-go/pkg/cache"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"golang.org/x/crypto/bcrypt"
 | 
						"golang.org/x/crypto/bcrypt"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -34,9 +35,6 @@ func CheckPwdHash(password, hash string) bool {
 | 
				
			|||||||
	return bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) == nil
 | 
						return bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) == nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 系统统一RSA秘钥对
 | 
					 | 
				
			||||||
var RsaPair []string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 生成RSA私钥和公钥字符串
 | 
					// 生成RSA私钥和公钥字符串
 | 
				
			||||||
// bits 证书大小
 | 
					// bits 证书大小
 | 
				
			||||||
// @return privateKeyStr publicKeyStr error
 | 
					// @return privateKeyStr publicKeyStr error
 | 
				
			||||||
@@ -130,33 +128,36 @@ func DefaultRsaDecrypt(data string, useBase64 bool) (string, error) {
 | 
				
			|||||||
	return string(val), nil
 | 
						return string(val), nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const publicKeyK = "mayfly:public-key"
 | 
				
			||||||
 | 
					const privateKeyK = "mayfly:private-key"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 获取系统的RSA公钥
 | 
					// 获取系统的RSA公钥
 | 
				
			||||||
func GetRsaPublicKey() (string, error) {
 | 
					func GetRsaPublicKey() (string, error) {
 | 
				
			||||||
	if len(RsaPair) == 2 {
 | 
						publicKey := cache.GetStr(publicKeyK)
 | 
				
			||||||
		return RsaPair[1], nil
 | 
						if publicKey != "" {
 | 
				
			||||||
 | 
							return publicKey, nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	privateKey, publicKey, err := GenerateRSAKey(1024)
 | 
						privateKey, publicKey, err := GenerateRSAKey(1024)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return "", err
 | 
							return "", err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	RsaPair = append(RsaPair, privateKey)
 | 
						cache.SetStr(publicKeyK, publicKey)
 | 
				
			||||||
	RsaPair = append(RsaPair, publicKey)
 | 
						cache.SetStr(privateKeyK, privateKey)
 | 
				
			||||||
	return publicKey, nil
 | 
						return publicKey, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 获取系统私钥
 | 
					// 获取系统私钥
 | 
				
			||||||
func GetRsaPrivateKey() (string, error) {
 | 
					func GetRsaPrivateKey() (string, error) {
 | 
				
			||||||
	if len(RsaPair) == 2 {
 | 
						privateKey := cache.GetStr(privateKeyK)
 | 
				
			||||||
		return RsaPair[0], nil
 | 
						if privateKey != "" {
 | 
				
			||||||
 | 
							return privateKey, nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	privateKey, publicKey, err := GenerateRSAKey(1024)
 | 
						privateKey, publicKey, err := GenerateRSAKey(1024)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return "", err
 | 
							return "", err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	RsaPair = append(RsaPair, privateKey)
 | 
						cache.SetStr(publicKeyK, publicKey)
 | 
				
			||||||
	RsaPair = append(RsaPair, publicKey)
 | 
						cache.SetStr(privateKeyK, privateKey)
 | 
				
			||||||
	return privateKey, nil
 | 
						return privateKey, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user