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 controllers

import (
	"github.com/gin-contrib/sessions"
	"github.com/gin-gonic/gin"
	"net/http"
)

package controllers

type Auth struct {
   
	Username string
	Password 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 routers

import (
	"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.Engine

func 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 MiB
	router.Static("/static", "static")
	router.LoadHTMLGlob("views/**/*")
	
	gob.Register(controllers.Auth{
   }) // TODO 这个必须有,没有就写不了cookie
	
	store := 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 main

import (
	"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/

相关推荐

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

    2023-12-27 06:50:05       49 阅读
  2. 第69讲后端登录逻辑实现

    2023-12-27 06:50:05       38 阅读
  3. uniapp登录逻辑

    2023-12-27 06:50:05       43 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-27 06:50:05       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-27 06:50:05       100 阅读
  3. 在Django里面运行非项目文件

    2023-12-27 06:50:05       82 阅读
  4. Python语言-面向对象

    2023-12-27 06:50:05       91 阅读

热门阅读

  1. 手写一个vuex?

    2023-12-27 06:50:05       56 阅读
  2. 【Springboot】解决 MacOS M1 上 Netty 的 DNS 解析错误

    2023-12-27 06:50:05       63 阅读
  3. K8s简述

    K8s简述

    2023-12-27 06:50:05      54 阅读
  4. Debian Linux完全卸载gitlab-ce

    2023-12-27 06:50:05       67 阅读
  5. 264. 丑数 II

    2023-12-27 06:50:05       61 阅读