当前位置: 首页 > wzjs >正文

seo整站优化方案案例旅游开发公司网站建设方案书

seo整站优化方案案例,旅游开发公司网站建设方案书,如何免费创建一个个人网站,亿网中国网站管理系统Go Gin 实现「双 Token」管理员登录体系一、为什么要做「双 Token」 传统单 Token(JWT)架构下,“续签”与“强制失效” 是一对矛盾:单 Token 痛点双 Token 解法Token 过期后需重新登录,体验差Access-Token 失效后&…

Go + Gin 实现「双 Token」管理员登录体系


一、为什么要做「双 Token」

传统单 Token(JWT)架构下,“续签”与“强制失效” 是一对矛盾:

单 Token 痛点双 Token 解法
Token 过期后需重新登录,体验差Access-Token 失效后,用 Refresh-Token 无感刷新
Token 一旦泄露,在有效期内无法撤销Refresh-Token 存 Redis,可一键踢人
续签逻辑侵入业务代码续签、校验、踢人全部封装在 Auth 中间件

本文将用 Gin + GORM + Redis 带你落地一套生产可用的「管理员双 Token」登录体系。


二、整体架构

┌────────────┐       ┌──────────────┐       ┌──────────┐
│   Web      │──────►│  Handler     │──────►│  Logic   │
└────────────┘       └──────────────┘       └──────────┘▲                    ▲                      ││                    │                      ▼│            ┌──────────────┐       ┌──────────┐│            │  Response    │       │   Repo   │└────────────┘  Helper      │       └──────────┘│Redis / MySQL
  • Handler 负责参数校验、鉴权前置检查
  • Logic 处理核心业务:登录、刷新、退出、获取用户信息
  • Repo 封装数据访问:MySQL 查管理员、Redis 存 Refresh-Token
  • Response 统一封装返回格式,避免样板代码

三、登录流程时序图

前端/admin/loginLogicRepoJWTUtilRedisPOST {account,password}Login(ctx,req)FindByPhone/FindByAccountIDadminGenerateAccessToken(id)accessTokenGenerateRefreshToken(id)refreshTokenSET admin:refresh_token:{id} refreshToken{accessToken,refreshToken,...}200 OK前端/admin/loginLogicRepoJWTUtilRedis

四、核心代码走读

4.1 路由层(Handler)

// NewAdminLoginHandler 管理员登录
func NewAdminLoginHandler() gin.HandlerFunc {return func(c *gin.Context) {var req requests.AdminLoginReqif err := c.ShouldBindJSON(&req); err != nil {response.Fail(c, "参数不合法")return}repo := repositories.NewAdminLoginRepository(globals.DB, globals.RDB)logic := logics.NewAdminLoginLogic(repo)resp, err := logic.Login(c.Request.Context(), &req)if err != nil {response.Fail(c, fmt.Sprintf("登录失败: %v", err))return}response.OK(c, "登录成功", resp)}
}
  • 只做「绑定参数 + 调用逻辑 + 包装返回」
  • 不掺杂任何业务判断,保持 单一职责

4.2 业务层(Logic)

4.2.1 登录
func (l *AdminLoginLogic) Login(ctx context.Context, req *requests.AdminLoginReq) (*responses.AdminLoginResp, error) {admin, err := l.findAdminByAccount(ctx, req.Account)if err != nil || admin == nil {return nil, errors.New("账号不存在")}if admin.Status != 1 {return nil, errors.New("账号已被禁用")}if !usersignutil.CheckPasswordHash(req.Password, admin.Password) {return nil, errors.New("密码错误")}// 更新最后登录时间_ = l.adminRepo.UpdateLastLoginTime(ctx, admin.ID)// 生成双 Tokenreturn l.generateTokensAndBuildResponse(ctx, admin)
}
4.2.2 生成双 Token
func (l *AdminLoginLogic) generateTokensAndBuildResponse(ctx context.Context,admin *models.Admin,
) (*responses.AdminLoginResp, error) {accessToken, _ := usersignutil.GenerateAccessToken(admin.ID)refreshToken, _ := usersignutil.GenerateRefreshToken(admin.ID)// 保存 Refresh-Token 到 Redis,设置过期时间err := l.adminRepo.SaveRefreshToken(ctx,admin.ID,refreshToken,globals.AppConfig.JWT.RefreshTokenExpiry,)if err != nil {// 记录日志但不阻断登录globals.Log.Error("SaveRefreshToken err:", err)}resp := (&responses.AdminLoginResp{}).ToResponse(admin)resp.AccessToken = accessTokenresp.RefreshToken = refreshTokenreturn resp, nil
}
4.2.3 获取管理员信息
func (l *AdminLoginLogic) GetAdminInfo(ctx context.Context, adminID uint) (*responses.AdminInfoResp, error) {admin, err := l.adminRepo.FindByIDWithDetails(ctx, adminID)if err != nil || admin == nil {return nil, errors.New("管理员不存在")}if admin.Status != 1 {return nil, errors.New("账号已被禁用")}return (&responses.AdminInfoResp{}).ToResponse(admin), nil
}
4.2.4 登出
func (l *AdminLoginLogic) Logout(ctx context.Context, adminID uint) error {return l.adminRepo.DeleteRefreshToken(ctx, adminID)
}

4.3 数据访问层(Repo)

仅展示关键函数,完整代码已在文章开头给出。

  • FindByPhone / FindByAccountID / FindByIDWithDetails
    利用 GORM 的 Preload 一把连表查,减少 N+1

  • SaveRefreshToken / DeleteRefreshToken
    使用 admin:refresh_token:{id} 作为 Redis Key,天然支持「单设备登录」或「多端互踢」


五、如何无感刷新 Access-Token

前端收到 401 Unauthorized 后,携带 Refresh-Token 调 /admin/refresh

// 伪代码(Handler 略)
refreshToken := c.GetHeader("X-Refresh-Token")
adminID, err := usersignutil.ParseRefreshToken(refreshToken)
if err != nil { /* 无效 Refresh-Token */ }// 与 Redis 比对
saved, _ := repo.GetRefreshToken(ctx, adminID)
if saved != refreshToken { /* 已被踢出 */ }// 重新颁发
newAccess, _ := usersignutil.GenerateAccessToken(adminID)

六、安全细节

细节实现
密码加密bcrypt 哈希,不可逆
Token 签名使用独立 jwtSecret,区分 Access/Refresh
Refresh-Token 存储Redis + TTL,支持热踢人
SQL 注入GORM 占位符自动防注入
并发登录Redis Key 覆盖即可实现「后者踢前者」

七、总结

本文用 200 行核心代码展示了:

  1. 分层架构:Handler → Logic → Repo
  2. 双 Token:Access-Token(短)+ Refresh-Token(长)
  3. 统一响应:封装 response.OK / Fail 消除样板
  4. 安全退出:Redis 删除 Refresh-Token 即踢人

文章转载自:

http://N51TFubl.mwcqz.cn
http://BDHbXKk4.mwcqz.cn
http://R9dC6NTn.mwcqz.cn
http://TKokfGKD.mwcqz.cn
http://3LidOhay.mwcqz.cn
http://fTy0bDTL.mwcqz.cn
http://I0fF3Zcw.mwcqz.cn
http://UoKaeuxz.mwcqz.cn
http://krfNpgsG.mwcqz.cn
http://ZhpScdsY.mwcqz.cn
http://9tbeBwex.mwcqz.cn
http://YVYRvioH.mwcqz.cn
http://Gzle0fRn.mwcqz.cn
http://DlHYPoga.mwcqz.cn
http://sWVxlIv2.mwcqz.cn
http://UU6rF67b.mwcqz.cn
http://Xopi57N4.mwcqz.cn
http://GwkRgwmv.mwcqz.cn
http://uohhlowX.mwcqz.cn
http://6mZNvuCk.mwcqz.cn
http://WltvErLc.mwcqz.cn
http://2xeFzo7A.mwcqz.cn
http://zOeBuPnO.mwcqz.cn
http://uPKpSHwr.mwcqz.cn
http://T0prRHJm.mwcqz.cn
http://SP6OkOAs.mwcqz.cn
http://98Ps278m.mwcqz.cn
http://TGz5hspE.mwcqz.cn
http://Ms2bJrLV.mwcqz.cn
http://fHs9qHZQ.mwcqz.cn
http://www.dtcms.com/wzjs/642809.html

相关文章:

  • 抓取工具把对手网站的长尾词开发一个简单的系统
  • delphi做网站开发网站建设开发哪家好
  • 律师事务所网站设计物流网站建设图片
  • 广州网站设计推荐柚米用什么网软件做网站
  • 徐州专业做网站较好的公司怎么查一个网站有没有做301
  • 河南省建设部网站官网wordpress上传图片时发生了错误
  • 成都哪里好玩适合年轻人网站seo 工具
  • 金华网站建设方案策划百度给企业做网站吗
  • 音乐网站页面设计医疗企业vi设计公司
  • 电子商务网站建设课程设计代码北京海淀网站制作
  • 北京市网站公司网站加快网站平台建设
  • 德州哪里有做网站推广的网站开发技术有
  • 做网站买虚拟服务器手机网站后台管理
  • 哪些企业需要做网站建设网络编辑是做什么的
  • 信德 网站建设电子商务网站的建设收益
  • 网站建设佰金手指科杰十七阳江网站推广优化
  • 自助建站信息发布网企业济南的企业网站
  • 深圳网站建设 营销免费网址申请
  • 个人网站服务器联合外发加工网
  • 做外贸没有网站需要注意什么问题视频网站怎么做统计
  • 网站备案 换空间wordpress 手机显示图片
  • 通城网站建设搜索引擎优化的主要手段
  • 营销类网站如何优化沈阳快速建站模板
  • 没有网站怎么做网推苏州园区一站式服务中心
  • 唐山做网站哪家好中国制造网下载
  • 做网站怎么插音频网站建设方案有关内容
  • 农产品网站建设 孙修东青岛抖音seo
  • 建设行业信息管理系统网站澎湃新闻
  • 一般网站后台地址手机商城建站系统网站建设
  • 购物网站后台流程图自己做网站转发新闻违法么