From bfef60806e0395d898f77e5a70d15a089e51f2fe Mon Sep 17 00:00:00 2001 From: yxh Date: Tue, 8 Mar 2022 18:26:22 +0800 Subject: [PATCH] =?UTF-8?q?=E7=99=BB=E5=BD=95=E6=97=A5=E5=BF=97=20token?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apiv1/system/user.go | 3 +- go.mod | 4 +- go.sum | 8 ++ internal/app/common/model/token.go | 37 ++++++++ internal/app/common/service/token.go | 51 +++++++++++ internal/app/system/controller/user.go | 43 ++++++++- .../app/system/model/entity/sys_login_log.go | 23 +++++ internal/app/system/model/sys_user_login.go | 18 ++++ .../internal/dao/internal/sys_login_log.go | 90 +++++++++++++++++++ .../service/internal/dao/sys_login_log.go | 24 +++++ .../service/internal/do/sys_login_log.go | 25 ++++++ internal/app/system/service/sys_login_log.go | 42 +++++++++ internal/app/system/service/sys_user.go | 41 ++++++++- internal/app/system/service/token.go | 36 ++++++++ manifest/config/config.yaml | 16 +++- 15 files changed, 453 insertions(+), 8 deletions(-) create mode 100644 internal/app/common/model/token.go create mode 100644 internal/app/common/service/token.go create mode 100644 internal/app/system/model/entity/sys_login_log.go create mode 100644 internal/app/system/model/sys_user_login.go create mode 100644 internal/app/system/service/internal/dao/internal/sys_login_log.go create mode 100644 internal/app/system/service/internal/dao/sys_login_log.go create mode 100644 internal/app/system/service/internal/do/sys_login_log.go create mode 100644 internal/app/system/service/sys_login_log.go create mode 100644 internal/app/system/service/token.go diff --git a/apiv1/system/user.go b/apiv1/system/user.go index fbb253b..a7c6b96 100644 --- a/apiv1/system/user.go +++ b/apiv1/system/user.go @@ -14,5 +14,6 @@ type UserLoginReq struct { } type UserLoginRes struct { g.Meta `mime:"text/html" example:""` - UserInfo *model.LoginUserRes + UserInfo *model.LoginUserRes `json:"userInfo"` + Token string `json:"token"` } diff --git a/go.mod b/go.mod index 37df702..1098d51 100644 --- a/go.mod +++ b/go.mod @@ -4,5 +4,7 @@ go 1.15 require ( github.com/gogf/gf/v2 v2.0.0-rc3 - github.com/mojocn/base64Captcha v1.3.5 // indirect + github.com/mojocn/base64Captcha v1.3.5 + github.com/mssola/user_agent v0.5.3 + github.com/tiger1103/gfast-token v0.0.3 ) diff --git a/go.sum b/go.sum index f76d05d..eaf82e2 100644 --- a/go.sum +++ b/go.sum @@ -22,6 +22,8 @@ github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LB github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/gogf/gf/v2 v2.0.0-rc3 h1:FkmLFhgOCZnyr24H/Yj9V1psS7fJ79DtPuSz+l/kwsc= github.com/gogf/gf/v2 v2.0.0-rc3/go.mod h1:apktt6TleWtCIwpz63vBqUnw8MX8gWKoZyxgDpXFtgM= +github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -54,6 +56,8 @@ github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/Qd github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mojocn/base64Captcha v1.3.5 h1:Qeilr7Ta6eDtG4S+tQuZ5+hO+QHbiGAJdi4PfoagaA0= github.com/mojocn/base64Captcha v1.3.5/go.mod h1:/tTTXn4WTpX9CfrmipqRytCpJ27Uw3G6I7NcP2WwcmY= +github.com/mssola/user_agent v0.5.3 h1:lBRPML9mdFuIZgI2cmlQ+atbpJdLdeVl2IDodjBR578= +github.com/mssola/user_agent v0.5.3/go.mod h1:TTPno8LPY3wAIEKRpAtkdMT0f8SE24pLRGPahjCH4uw= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= @@ -73,6 +77,10 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/tiger1103/gfast-token v0.0.2 h1:z2WfVAQV4ocKJeAL90pMVW2ryHVv2pijFG1GZffQ/EI= +github.com/tiger1103/gfast-token v0.0.2/go.mod h1:RnVRqmWD3h4qfTU1vJNXNhQjh2L5ht1vxLnjwShwGuY= +github.com/tiger1103/gfast-token v0.0.3 h1:uXZMeNXSb5j/GNLHAgkhwzhG/1M3eL3Ho0RNfl5LUpw= +github.com/tiger1103/gfast-token v0.0.3/go.mod h1:RnVRqmWD3h4qfTU1vJNXNhQjh2L5ht1vxLnjwShwGuY= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.opentelemetry.io/otel v1.0.0 h1:qTTn6x71GVBvoafHK/yaRUmFzI4LcONZD0/kXxl5PHI= diff --git a/internal/app/common/model/token.go b/internal/app/common/model/token.go new file mode 100644 index 0000000..b67c44f --- /dev/null +++ b/internal/app/common/model/token.go @@ -0,0 +1,37 @@ +/* +* @desc:token options +* @company:云南奇讯科技有限公司 +* @Author: yixiaohu +* @Date: 2022/3/8 16:02 + */ + +package model + +import ( + "github.com/gogf/gf/v2/frame/g" +) + +const ( + CacheModelMem = "memory" + CacheModelRedis = "redis" +) + +type TokenOptions struct { + // server name + ServerName string `json:"serverName"` + // 缓存key (每创建一个实例CacheKey必须不相同) + CacheKey string `json:"cacheKey"` + // 超时时间 默认10天(秒) + Timeout int64 `json:"timeout"` + // 缓存刷新时间 默认5天(秒) + // 处理携带token的请求时当前时间大于超时时间并小于缓存刷新时间时token将自动刷新即重置token存活时间 + // MaxRefresh值为0时,token将不会自动刷新 + MaxRefresh int64 `json:"maxRefresh"` + // 是否允许多点登录 + MultiLogin bool `json:"multiLogin"` + // Token加密key 32位 + EncryptKey []byte `json:"encryptKey"` + // 拦截排除地址 + ExcludePaths g.SliceStr `json:"excludePaths"` + CacheModel string `json:"cacheModel"` +} diff --git a/internal/app/common/service/token.go b/internal/app/common/service/token.go new file mode 100644 index 0000000..97c8c6b --- /dev/null +++ b/internal/app/common/service/token.go @@ -0,0 +1,51 @@ +/* +* @desc:token功能 +* @company:云南奇讯科技有限公司 +* @Author: yixiaohu +* @Date: 2022/3/8 15:54 + */ + +package service + +import ( + "context" + "github.com/gogf/gf/v2/net/ghttp" + "github.com/tiger1103/gfast-token/gftoken" + "github.com/tiger1103/gfast/v3/internal/app/common/model" +) + +type IGfToken interface { + GenerateToken(ctx context.Context, key string, data interface{}) (keys string, err error) + Middleware(group *ghttp.RouterGroup) error + ParseToken(r *ghttp.Request) (*gftoken.CustomClaims, error) +} + +type gfTokenImpl struct { + *gftoken.GfToken +} + +var gT = gfTokenImpl{ + GfToken: gftoken.NewGfToken(), +} + +func GfToken(options *model.TokenOptions) IGfToken { + if options.CacheModel == model.CacheModelRedis { + gT.GfToken = gftoken.NewGfToken( + gftoken.WithCacheKey(options.CacheKey), + gftoken.WithTimeout(options.Timeout), + gftoken.WithMaxRefresh(options.MaxRefresh), + gftoken.WithMultiLogin(options.MultiLogin), + gftoken.WithExcludePaths(options.ExcludePaths), + gftoken.WithGRedis(), + ) + } else { + gT.GfToken = gftoken.NewGfToken( + gftoken.WithCacheKey(options.CacheKey), + gftoken.WithTimeout(options.Timeout), + gftoken.WithMaxRefresh(options.MaxRefresh), + gftoken.WithMultiLogin(options.MultiLogin), + gftoken.WithExcludePaths(options.ExcludePaths), + ) + } + return IGfToken(&gT) +} diff --git a/internal/app/system/controller/user.go b/internal/app/system/controller/user.go index cab5764..6b21916 100644 --- a/internal/app/system/controller/user.go +++ b/internal/app/system/controller/user.go @@ -2,12 +2,15 @@ package controller import ( "context" + "github.com/gogf/gf/v2/crypto/gmd5" "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/os/genv" + "github.com/gogf/gf/v2/util/gconv" "github.com/tiger1103/gfast/v3/apiv1/system" commonService "github.com/tiger1103/gfast/v3/internal/app/common/service" "github.com/tiger1103/gfast/v3/internal/app/system/model" "github.com/tiger1103/gfast/v3/internal/app/system/service" + "github.com/tiger1103/gfast/v3/library/libUtils" ) var ( @@ -19,7 +22,10 @@ type UserController struct { } func (c *UserController) Login(ctx context.Context, req *system.UserLoginReq) (res *system.UserLoginRes, err error) { - var user *model.LoginUserRes + var ( + user *model.LoginUserRes + token string + ) //判断验证码是否正确 debug := genv.GetWithCmd("gf.debug") if debug.Int() != 1 { @@ -28,14 +34,45 @@ func (c *UserController) Login(ctx context.Context, req *system.UserLoginReq) (r return } } - //ip := libUtils.GetClientIp(ctx) - //userAgent := libUtils.GetUserAgent(ctx) + ip := libUtils.GetClientIp(ctx) + userAgent := libUtils.GetUserAgent(ctx) user, err = service.User().GetAdminUserByUsernamePassword(ctx, req) + if err != nil { + // 保存登录失败的日志信息 + service.SysLoginLog().Invoke(ctx, &model.LoginLogParams{ + Status: 0, + Username: req.Username, + Ip: ip, + UserAgent: userAgent, + Msg: err.Error(), + Module: "系统后台", + }) + return + } + err = service.User().UpdateLoginInfo(ctx, user.Id, ip) + if err != nil { + return + } + // 报存登录成功的日志信息 + service.SysLoginLog().Invoke(ctx, &model.LoginLogParams{ + Status: 1, + Username: req.Username, + Ip: ip, + UserAgent: userAgent, + Msg: "登录成功", + Module: "系统后台", + }) + token, err = service.GfToken(ctx).GenerateToken( + ctx, + gconv.String(user.Id)+"-"+gmd5.MustEncryptString(user.UserName)+gmd5.MustEncryptString(user.UserPassword), + user, + ) if err != nil { return } res = &system.UserLoginRes{ UserInfo: user, + Token: token, } return } diff --git a/internal/app/system/model/entity/sys_login_log.go b/internal/app/system/model/entity/sys_login_log.go new file mode 100644 index 0000000..9bac7b9 --- /dev/null +++ b/internal/app/system/model/entity/sys_login_log.go @@ -0,0 +1,23 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. Created at 2022-03-08 11:31:48 +// ================================================================================= + +package entity + +import ( + "github.com/gogf/gf/v2/os/gtime" +) + +// SysLoginLog is the golang structure for table sys_login_log. +type SysLoginLog struct { + InfoId int64 `json:"infoId" description:"访问ID"` + LoginName string `json:"loginName" description:"登录账号"` + Ipaddr string `json:"ipaddr" description:"登录IP地址"` + LoginLocation string `json:"loginLocation" description:"登录地点"` + Browser string `json:"browser" description:"浏览器类型"` + Os string `json:"os" description:"操作系统"` + Status int `json:"status" description:"登录状态(0成功 1失败)"` + Msg string `json:"msg" description:"提示消息"` + LoginTime *gtime.Time `json:"loginTime" description:"登录时间"` + Module string `json:"module" description:"登录模块"` +} diff --git a/internal/app/system/model/sys_user_login.go b/internal/app/system/model/sys_user_login.go new file mode 100644 index 0000000..50ffdba --- /dev/null +++ b/internal/app/system/model/sys_user_login.go @@ -0,0 +1,18 @@ +/* +* @desc:登录日志 +* @company:云南奇讯科技有限公司 +* @Author: yixiaohu +* @Date: 2022/3/8 11:43 + */ + +package model + +// LoginLogParams 登录日志写入参数 +type LoginLogParams struct { + Status int + Username string + Ip string + UserAgent string + Msg string + Module string +} diff --git a/internal/app/system/service/internal/dao/internal/sys_login_log.go b/internal/app/system/service/internal/dao/internal/sys_login_log.go new file mode 100644 index 0000000..f33fe3e --- /dev/null +++ b/internal/app/system/service/internal/dao/internal/sys_login_log.go @@ -0,0 +1,90 @@ +// ========================================================================== +// Code generated by GoFrame CLI tool. DO NOT EDIT. Created at 2022-03-08 11:31:48 +// ========================================================================== + +package internal + +import ( + "context" + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// SysLoginLogDao is the data access object for table sys_login_log. +type SysLoginLogDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of current DAO. + columns SysLoginLogColumns // columns contains all the column names of Table for convenient usage. +} + +// SysLoginLogColumns defines and stores column names for table sys_login_log. +type SysLoginLogColumns struct { + InfoId string // 访问ID + LoginName string // 登录账号 + Ipaddr string // 登录IP地址 + LoginLocation string // 登录地点 + Browser string // 浏览器类型 + Os string // 操作系统 + Status string // 登录状态(0成功 1失败) + Msg string // 提示消息 + LoginTime string // 登录时间 + Module string // 登录模块 +} + +// sysLoginLogColumns holds the columns for table sys_login_log. +var sysLoginLogColumns = SysLoginLogColumns{ + InfoId: "info_id", + LoginName: "login_name", + Ipaddr: "ipaddr", + LoginLocation: "login_location", + Browser: "browser", + Os: "os", + Status: "status", + Msg: "msg", + LoginTime: "login_time", + Module: "module", +} + +// NewSysLoginLogDao creates and returns a new DAO object for table data access. +func NewSysLoginLogDao() *SysLoginLogDao { + return &SysLoginLogDao{ + group: "default", + table: "sys_login_log", + columns: sysLoginLogColumns, + } +} + +// DB retrieves and returns the underlying raw database management object of current DAO. +func (dao *SysLoginLogDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of current dao. +func (dao *SysLoginLogDao) Table() string { + return dao.table +} + +// Columns returns all column names of current dao. +func (dao *SysLoginLogDao) Columns() SysLoginLogColumns { + return dao.columns +} + +// Group returns the configuration group name of database of current dao. +func (dao *SysLoginLogDao) Group() string { + return dao.group +} + +// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation. +func (dao *SysLoginLogDao) Ctx(ctx context.Context) *gdb.Model { + return dao.DB().Model(dao.table).Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rollbacks the transaction and returns the error from function f if it returns non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note that, you should not Commit or Rollback the transaction in function f +// as it is automatically handled by this function. +func (dao *SysLoginLogDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/internal/app/system/service/internal/dao/sys_login_log.go b/internal/app/system/service/internal/dao/sys_login_log.go new file mode 100644 index 0000000..0f06d56 --- /dev/null +++ b/internal/app/system/service/internal/dao/sys_login_log.go @@ -0,0 +1,24 @@ +// ================================================================================= +// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish. +// ================================================================================= + +package dao + +import ( + "github.com/tiger1103/gfast/v3/internal/app/system/service/internal/dao/internal" +) + +// sysLoginLogDao is the data access object for table sys_login_log. +// You can define custom methods on it to extend its functionality as you wish. +type sysLoginLogDao struct { + *internal.SysLoginLogDao +} + +var ( + // SysLoginLog is globally public accessible object for table sys_login_log operations. + SysLoginLog = sysLoginLogDao{ + internal.NewSysLoginLogDao(), + } +) + +// Fill with you ideas below. diff --git a/internal/app/system/service/internal/do/sys_login_log.go b/internal/app/system/service/internal/do/sys_login_log.go new file mode 100644 index 0000000..d68762e --- /dev/null +++ b/internal/app/system/service/internal/do/sys_login_log.go @@ -0,0 +1,25 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. Created at 2022-03-08 11:31:48 +// ================================================================================= + +package do + +import ( + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +// SysLoginLog is the golang structure of table sys_login_log for DAO operations like Where/Data. +type SysLoginLog struct { + g.Meta `orm:"table:sys_login_log, do:true"` + InfoId interface{} // 访问ID + LoginName interface{} // 登录账号 + Ipaddr interface{} // 登录IP地址 + LoginLocation interface{} // 登录地点 + Browser interface{} // 浏览器类型 + Os interface{} // 操作系统 + Status interface{} // 登录状态(0成功 1失败) + Msg interface{} // 提示消息 + LoginTime *gtime.Time // 登录时间 + Module interface{} // 登录模块 +} diff --git a/internal/app/system/service/sys_login_log.go b/internal/app/system/service/sys_login_log.go new file mode 100644 index 0000000..49eb2b4 --- /dev/null +++ b/internal/app/system/service/sys_login_log.go @@ -0,0 +1,42 @@ +/* +* @desc:登录日志处理 +* @company:云南奇讯科技有限公司 +* @Author: yixiaohu +* @Date: 2022/3/8 11:42 + */ + +package service + +import ( + "context" + "github.com/gogf/gf/v2/os/grpool" + "github.com/tiger1103/gfast/v3/internal/app/system/model" +) + +type ISysLoginLog interface { + Invoke(ctx context.Context, data *model.LoginLogParams) +} + +type sysLoginLogImpl struct { + Pool *grpool.Pool +} + +var ( + sysLoginLog = sysLoginLogImpl{ + Pool: grpool.New(100), + } +) + +func SysLoginLog() ISysLoginLog { + return ISysLoginLog(&sysLoginLog) +} + +func (s *sysLoginLogImpl) Invoke(ctx context.Context, data *model.LoginLogParams) { + s.Pool.Add( + ctx, + func(ctx context.Context) { + //写入日志数据 + User().LoginLog(ctx, data) + }, + ) +} diff --git a/internal/app/system/service/sys_user.go b/internal/app/system/service/sys_user.go index 315193b..aa328dc 100644 --- a/internal/app/system/service/sys_user.go +++ b/internal/app/system/service/sys_user.go @@ -11,9 +11,12 @@ import ( "context" "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" + "github.com/mssola/user_agent" "github.com/tiger1103/gfast/v3/apiv1/system" "github.com/tiger1103/gfast/v3/internal/app/system/model" "github.com/tiger1103/gfast/v3/internal/app/system/service/internal/dao" + "github.com/tiger1103/gfast/v3/internal/app/system/service/internal/do" "github.com/tiger1103/gfast/v3/library/libUtils" "github.com/tiger1103/gfast/v3/library/liberr" ) @@ -28,6 +31,8 @@ func User() IUser { type IUser interface { GetAdminUserByUsernamePassword(ctx context.Context, req *system.UserLoginReq) (user *model.LoginUserRes, err error) + LoginLog(ctx context.Context, params *model.LoginLogParams) + UpdateLoginInfo(ctx context.Context, id uint64, ip string) (err error) } type userImpl struct { @@ -54,8 +59,40 @@ func (s *userImpl) GetAdminUserByUsernamePassword(ctx context.Context, req *syst func (s *userImpl) GetUserByUsername(ctx context.Context, userName string) (user *model.LoginUserRes, err error) { err = g.Try(func() { user = &model.LoginUserRes{} - err = dao.SysUser.Ctx(ctx).Fields(user).Where("a=12").Where(dao.SysUser.Columns().UserName, userName).Scan(user) - liberr.ErrIsNil(ctx, err, "获取用户信息失败") + err = dao.SysUser.Ctx(ctx).Fields(user).Where(dao.SysUser.Columns().UserName, userName).Scan(user) + liberr.ErrIsNil(ctx, err, "账号密码错误") + }) + return +} + +// LoginLog 记录登录日志 +func (s *userImpl) LoginLog(ctx context.Context, params *model.LoginLogParams) { + ua := user_agent.New(params.UserAgent) + browser, _ := ua.Browser() + loginData := &do.SysLoginLog{ + LoginName: params.Username, + Ipaddr: params.Ip, + LoginLocation: libUtils.GetCityByIp(params.Ip), + Browser: browser, + Os: ua.OS(), + Status: params.Status, + Msg: params.Msg, + LoginTime: gtime.Now(), + Module: params.Module, + } + _, err := dao.SysLoginLog.Ctx(ctx).Insert(loginData) + if err != nil { + g.Log().Error(ctx, err) + } +} + +func (s *userImpl) UpdateLoginInfo(ctx context.Context, id uint64, ip string) (err error) { + g.Try(func() { + _, err = dao.SysUser.Ctx(ctx).WherePri(id).Update(g.Map{ + dao.SysUser.Columns().LastLoginIp: ip, + dao.SysUser.Columns().LastLoginTime: gtime.Now(), + }) + liberr.ErrIsNil(ctx, err, "更新用户登录信息失败") }) return } diff --git a/internal/app/system/service/token.go b/internal/app/system/service/token.go new file mode 100644 index 0000000..21c74cb --- /dev/null +++ b/internal/app/system/service/token.go @@ -0,0 +1,36 @@ +/* +* @desc:后台token处理 +* @company:云南奇讯科技有限公司 +* @Author: yixiaohu +* @Date: 2022/3/8 17:10 + */ + +package service + +import ( + "context" + "github.com/gogf/gf/v2/frame/g" + "github.com/tiger1103/gfast/v3/internal/app/common/model" + commonService "github.com/tiger1103/gfast/v3/internal/app/common/service" + "github.com/tiger1103/gfast/v3/library/liberr" + "sync" +) + +var ( + options *model.TokenOptions + gT commonService.IGfToken + lock = &sync.Mutex{} +) + +func GfToken(ctx context.Context) commonService.IGfToken { + if gT == nil { + lock.Lock() + defer lock.Unlock() + if gT == nil { + err := g.Cfg().MustGet(ctx, "gfToken").Struct(&options) + liberr.ErrIsNil(ctx, err) + gT = commonService.GfToken(options) + } + } + return gT +} diff --git a/manifest/config/config.yaml b/manifest/config/config.yaml index a4d4321..a02666e 100644 --- a/manifest/config/config.yaml +++ b/manifest/config/config.yaml @@ -28,17 +28,31 @@ database: logger: level: "all" stdout: true + Path: "resource/log/sql" default: link: "mysql:root:123456@tcp(127.0.0.1:3306)/gfast-v3" debug: true + charset: "utf8mb4" #数据库编码 + dryRun: false #空跑 + maxIdle: 10 #连接池最大闲置的连接数 + maxOpen: 10 #连接池最大打开的连接数 + maxLifetime: 30 #(单位秒)连接对象可重复使用的时间长度 + +gfToken: + cacheKey: "gfToken_" + timeOut: 10800 + maxRefresh: 5400 + multiLogin: true + encryptKey: "49c54195e750b04e74a8429b17896586" + cacheModel: "redis" # CLI. gfcli: gen: dao: - link: "mysql:root:123456@tcp(127.0.0.1:3306)/gfast-v3" - tables: "sys_user" + tables: "sys_login_log" removePrefix: "gf_" descriptionTag: true noModelComment: true