gin实现登录逻辑,包含cookie,session

users/login.html

{{define "users/login.html"}}
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>登录页面</title>
</head>
<body><form method="post" action="/login">username:<input style="align-content: center" type="text" name="username" onfocus="change()"><br/>password:<input type="password" name="password" onfocus="change()"><br/><input type="submit" value="login"></form><h1 id = "tag" style="color: red">{{.Message}}</h1>
</body>
<script>function change() {let tag = document.getElementById("tag");tag.innerHTML="<h1></h1>";}
</script>
</html>
{{end}}

default/index.html

{{define "default/index.html"}}
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>index页面</title>
</head>
<body>
<h1 style="color: chocolate; align-content: center">{{.Content}}</h1>
</body>
</html>
{{end}}

controllers/users.go

package controllersimport ("github.com/gin-contrib/sessions""github.com/gin-gonic/gin""net/http"
)package controllerstype Auth struct {Username stringPassword string
}const DefaultAuthInfoKey = "AUTH"func LoginGet() gin.HandlerFunc {return func(ctx *gin.Context) {ctx.HTML(http.StatusOK, "users/login.html", nil)}
}func LogoutGet() gin.HandlerFunc {return func(ctx *gin.Context) {session := sessions.Default(ctx)session.Delete(DefaultAuthInfoKey)session.Options(sessions.Options{Path:     "/",Domain:   "localhost",MaxAge:   0,Secure:   true,HttpOnly: false,SameSite: 0,})session.Save()ctx.Redirect(http.StatusFound, "/login")ctx.Abort()}
}func LoginPost() gin.HandlerFunc {return func(ctx *gin.Context) {username := ctx.PostForm("username")password := ctx.PostForm("password")if username != "admin" || password != "admin" {ctx.HTML(http.StatusOK, "users/login.html", gin.H{"Message": "用户名或密码错误!",})ctx.Abort()return}//登录成功auth := Auth{Username: username, Password: password}ctx.Set(DefaultAuthInfoKey, auth)session := sessions.Default(ctx)session.Set(DefaultAuthInfoKey, auth)session.Save() //TODO 必须Save,否则不生效ctx.Redirect(http.StatusFound, "/")}
}func Index() gin.HandlerFunc {return func(ctx *gin.Context) {ctx.HTML(http.StatusOK, "default/index.html", gin.H{"Content": "欢迎回来:" + ctx.MustGet(DefaultAuthInfoKey).(Auth).Username,})}
}

routers/router.go

package routersimport ("encoding/gob""github.com/coolbit/gin_sample/controllers""github.com/coolbit/gin_sample/middleware""github.com/gin-contrib/sessions""github.com/gin-contrib/sessions/cookie""github.com/gin-gonic/gin""net/http"
)var router *gin.Enginefunc GetRouter() *gin.Engine {return router
}func AuthRequired() gin.HandlerFunc {return func(ctx *gin.Context) {session := sessions.Default(ctx)auth := session.Get(controllers.DefaultAuthInfoKey)au, ok := auth.(controllers.Auth)if !ok || au.Username == "" {ctx.Redirect(http.StatusFound, "/login")ctx.Abort()return}ctx.Set(controllers.DefaultAuthInfoKey, auth) // 设置权限信息,供给当前请求链路使用session.Options(sessions.Options{             // 必须Save后才生效Path:     "/",Domain:   "localhost",MaxAge:   7 * 24 * 60 * 60, // 7天Secure:   true,HttpOnly: false,SameSite: 0,})session.Set(controllers.DefaultAuthInfoKey, au)session.Save() //"已刷新session"}
}func init() {router = gin.Default()// Set a lower memory limit for multipart forms (default is 32 MiB)router.MaxMultipartMemory = 8 << 20 // 8 MiBrouter.Static("/static", "static")router.LoadHTMLGlob("views/**/*")gob.Register(controllers.Auth{}) // TODO 这个必须有,没有就写不了cookiestore := cookie.NewStore([]byte("我是密钥"))router.Use(sessions.Sessions("SESSION_ID", store))router.GET("/login", controllers.LoginGet())router.POST("/login", controllers.LoginPost())router.Use(AuthRequired()) // 鉴权插件设置在这里router.GET("/", controllers.Index())
}

main.go

package mainimport ("github.com/coolbit/gin_sample/routers"
)func main() {routers.GetRouter().Run(":80")
}

登录后才能使用的系统的登录逻辑,借助cookie,session

  1. 客户端发起http://localhost/请求。
  2. 请求须经过后端AuthRequired中间件鉴权。该中间件查看session中是否保存了请求携带的cookie对应的用户信息,若有。则登录成功;若没有,则重定向到http://localhost/login进行登录。
  3. GET方法请求http://localhost/login时只返回页面,不需鉴权逻辑。
  4. POST方法请求http://localhost/login时,不需鉴权逻辑。进行登录验证,并记录session,为当前context设置Key为"AUTH"的有效用户信息。方便该次请求链路使用。登录成功则重定向到http://localhost/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/579190.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用TLS/SSL Pinning保护安卓应用程序

使用TLS/SSL Pinning保护安卓应用程序 在现代术语中&#xff0c;“SSL”&#xff08;安全套接层&#xff09;通常指的是“TLS”&#xff08;传输层安全&#xff09;。虽然 SSL 和 TLS 不是同一个东西&#xff0c;但 TLS 是 SSL 的改进和更安全的版本&#xff0c;并且在实践中已…

51.网游逆向分析与插件开发-游戏反调试功能的实现-设置主线程为隐藏调试破坏调试通道

前置内容&#xff1a; 50.网游逆向分析与插件开发-游戏反调试功能的实现-TP、NP等反调试驱动的原理-CSDN博客 码云地址&#xff08;master分支&#xff09;&#xff1a;https://gitee.com/dye_your_fingers/sro_-ex.git 码云版本号&#xff1a;87e45c4acc2e842f147ce0e037731f…

在k8s中将gitlab-runner的运行pod调度到指定节点

本篇和前面的 基于helm的方式在k8s集群中部署gitlab 具有很强的关联性&#xff0c;因此如果有不明白的地方可以查看往期分享&#xff1a; 基于helm的方式在k8s集群中部署gitlab - 部署基于helm的方式在k8s集群中部署gitlab - 备份恢复基于helm的方式在k8s集群中部署gitlab - 升…

Copilot概述:AI助手引领编程新纪元

前言&#xff1a; 随着人工智能&#xff08;AI&#xff09;技术的不断进步&#xff0c;编程领域也在逐渐迎来一场革命。GitHub Copilot&#xff0c;作为一款由 OpenAI 和 GitHub 合作开发的编程助手&#xff0c;引发了广泛的关注和讨论。本篇博客将全面概述 Copilot 的背景、功…

基于gradio快速部署自己的深度学习模型(目标检测、图像分类、语义分割模型)

gradio是一款基于python的算法快速部署工具&#xff0c;本博文主要介绍使用gradio部署目标检测、图像分类、语义分割模型的部署。相比于flask&#xff0c;使用gradio不需要自己构造前端代码&#xff0c;只需要将后端接口写好即可。此外&#xff0c;基于gradio实现的项目&#x…

算法分析的

&#xff08;1&#xff09;一个顾客买了价值x元的商品&#xff08;不考虑角、分&#xff09;&#xff0c;并将y元的钱交给售货员&#xff1a;编写代码&#xff1a;在各种币值的钱都很充分的情况下&#xff0c;使售货员能用张数最少的钱币找给顾客 #include<stdio.h> int…

舒心减压,益路同行,黄埔区惠民社会服务中心开展残障人士冬至漫游活动

“走出家门&#xff0c;共享阳光”残障人士游读广州项目是由广州市慈善会、广州市善城社区公益基金会资助、广州市黄埔区惠民社会服务中心实施的第四届“创善*微创投”广州市社区公益微创投项目&#xff0c;黄埔区康园工疗站约120名残障人士为服务对象&#xff0c;通过游玩与教…

leetcode 371. 两整数之和(优质解法)

链接&#xff1a;371. 两整数之和 代码&#xff1a; class Solution {public int getSum(int a, int b) {while(b!0){int numa^b; //无进位值int bit(a&b)<<1; //进位anum;bbit;}return a;} } 题解&#xff1a; 要计算两个数相加并且不能使用 - 号&#xff0…

【代码混淆】react-native 代码混淆

​ 混淆是指对源代码进行加密、重命名等操作&#xff0c;以增加代码的复杂度&#xff0c;使其难以理解和反编译。 在React Native中&#xff0c;混淆可以通过以下步骤实现&#xff1a; 将JavaScript源代码转换为基于本机平台的二进制代码&#xff0c;可以使用工具如Metro Bun…

【ARM 嵌入式 编译系列 10.4 -- 生成二进制文件】

文章目录 二进制文件生成dd 命令copy文件使用16进制对二进制文件显示 二进制文件生成 在嵌入的工作中&#xff0c;经常会使用到二进制文件&#xff0c;那么我们如何自己生成一个二进制文件呢&#xff1f;接下来介绍如何将一个只包含将32位数据的文件转化为二进制文件&#xff…

人工智能顶会CVPR2022《革新AI预训练:探索KDEP及其在知识蒸馏中的破局之道》论文解读

这里写目录标题 1.引言KDEP的核心概念&#xff1a;与传统知识蒸馏的区别&#xff1a; 2.KDEP方法KDEP的基本设置&#xff1a;KDEP的目标&#xff1a;非参数方法在特征尺寸对齐中的作用非参数对齐的工作原理&#xff1a;**SVD的工作原理**&#xff1a;PTS的基本思想&#xff1a;…

如何在 TypeScript 中遍历 Enum 的两种方案

背景 TypeScript 中有一个 JavaScript 中没有的声明关键字&#xff0c;即 enum ,在 TypeScript 项目开发过程中&#xff0c;我发现使用枚举enum的概率是极高的。枚举是一种特殊的数据类型&#xff0c;它允许开发者定义一个静态变量集合。枚举类型帮助开发者清晰的预设集合中的…

HarmonyOS4.0系统性深入开发04UIAbility组件详解(下)

UIAbility组件间交互&#xff08;设备内&#xff09; UIAbility是系统调度的最小单元。在设备内的功能模块之间跳转时&#xff0c;会涉及到启动特定的UIAbility&#xff0c;该UIAbility可以是应用内的其他UIAbility&#xff0c;也可以是其他应用的UIAbility&#xff08;例如启…

DBeaver Community(社区版)下载及安装自用版

DBeaver Community&#xff08;社区版&#xff09;下载及安装自用版 数据库管理工具好用的都收费&#xff0c;收费的都好用。 DBeaver Community&#xff08;社区版&#xff09;免费&#xff0c;功能够用&#xff0c;性能可以&#xff0c;推荐。商业版的强大&#xff0c;收费&a…

网络知识点之-MPLS VPN

随着网络经济的发展&#xff0c;企业对于自身网络的建设提出了越来越高的要求&#xff0c;主要表现在网络的灵活性、经济性、扩展性等方面。在这样的背景下&#xff0c;VPN以其独有的优势赢得了越来越多企业的青睐。利用公共网络来构建的私有专用网络称为虚拟私有网络&#xff…

leetcode 面试题 17.19. 消失的两个数字 (hard)(优质解法)

链接&#xff1a;面试题 17.19. 消失的两个数字 代码&#xff1a; class Solution {public int[] missingTwo(int[] nums) {int lengthnums.length;int tmp0;//将完整数据以及 nums 中的数据都进行异或&#xff0c;得到的就是缺失的两个数字 a^b 的结果for(int i1;i<length…

vue3项目 - 使用 pnpm 包管理器来创建项目

创建项目 npm install -g pnpm pnpm create vue 输入项目名称、包名称、选择要安装的依赖&#xff0c;最后 pnpm install pnpm format #规范格式 pnpm dev #启动项目

jQuery的事件-动画-AJAX和插件

一、jQuery事件处理 1.认识事件&#xff08;Event&#xff09; Web页面经常需要和用户之间进行交互&#xff0c;而交互的过程中我们可能想要捕捉这个交互的过程&#xff1a; 比如用户点击了某个按钮、用户在输入框里面输入了某个文本、用户鼠标经过了某个位置&#xff1b;浏…

使用vite创建vue3项目

1、使用管理员身份打开命令行窗口&#xff0c;输入命令: npm create vuelatest TypeScript语法选择是&#xff0c;其他依次选择否&#xff0c;创建完毕。 2、 创建完毕后打开项目&#xff0c;vscode会提示安装开发相关的插件&#xff0c;选择install 3、打开vscode终端&#x…

【力扣】199.二叉树的右视图

看到这个题目的一瞬间&#xff0c;我想递归&#xff0c;必须用递归。最近被递归折磨的有点狠&#xff0c;但是我感觉我快要打败它了&#xff0c;就是现在稍稍有点处于劣势。不过没关系&#xff0c;来日方长不是。 法一&#xff1a;递归 题解&#xff1a; 之前想的就是先递归&…