Manual de operação de cookies e sessões do Gin Framework em linguagem Go (10)

Na estrutura Gin, use ctx.SetCookie()métodos para definir cookies. A seguir está um exemplo de implementação específico:

func setCookie(c *gin.Context) {
    // 设置Cookie的参数和值
    c.SetCookie("my_cookie", "example value", 3600, "/", "localhost", false, true)
    
    // 其他逻辑
}

Neste exemplo, usamos c.SetCookie()o método para definir o cookie. Os parâmetros recebidos pelo método são os seguintes:

  • O primeiro parâmetro é o nome do cookie.
  • O segundo parâmetro é o valor do cookie.
  • O terceiro parâmetro é o tempo de expiração do cookie em segundos. Neste exemplo, defina o tempo de expiração do cookie para 3.600 segundos (ou seja, 1 hora).
  • O quarto parâmetro é o caminho do cookie, especificando o caminho onde o cookie está disponível. Neste exemplo, definimos como caminho raiz "/".
  • O quinto parâmetro é o domínio do cookie, especificando o nome do domínio onde o cookie está disponível. Neste exemplo, definimos como "localhost", o que significa que só pode ser usado no ambiente de teste local.
  • O sexto parâmetro é um valor booleano que indica se deve usar HTTPS para enviar cookies. Neste exemplo, definimos como falso.
  • O sétimo parâmetro é um valor booleano que indica se o atributo SameSite está habilitado. Neste exemplo, definimos como verdadeiro.

Com esta configuração, o cookie pode ser enviado ao cliente na resposta, e o cliente irá armazená-lo automaticamente e enviá-lo de volta ao servidor nas solicitações subsequentes.

visualizar modelo 

Defina o valor do cookie no controlador;


func (con AdminControllers) Views(c *gin.Context) {

	c.SetCookie("username", "王二妹", 3600, "/", "localhost", false, true)

	c.HTML(http.StatusOK, "admin/views/index.html", gin.H{
		"title": "views页面",
	})
}

O cookie existe após o prazo de validade? 

Resposta: Quando o tempo de expiração de um cookie atingir, o navegador não enviará mais o cookie ao servidor. Ou seja, o cookie é considerado expirado pelo navegador e não é mais transmitido pelo navegador.

Embora o navegador não envie mais um cookie expirado, o cookie ainda pode existir no armazenamento de cookies do cliente. Navegadores diferentes têm comportamentos diferentes. Alguns navegadores excluirão o cookie imediatamente após a expiração, enquanto outros manterão o cookie expirado até que o cache do navegador seja limpo ou o usuário o exclua ativamente.

No código do lado do servidor, você não pode inspecionar diretamente o armazenamento de cookies do cliente. O servidor receberá apenas cookies válidos enviados pelo navegador (ou seja, cookies que não expiraram).

Portanto, mesmo que o tempo de expiração tenha sido atingido, você ainda poderá receber o cookie expirado no servidor até que o navegador o exclua.

Para evitar o processamento de cookies expirados, você pode verificar se o cookie recebido está dentro do período de validade no lado do servidor. Se tiver expirado, não será processado posteriormente.

Como deletar os campos definidos pelos cookies?

Na estrutura Gin, para excluir um cookie, você pode usar  c.SetCookie() o método e definir seu tempo de expiração para um carimbo de data/hora no passado. Isso fará com que o navegador marque imediatamente o cookie como expirado e o exclua.

Aqui está um exemplo:

func deleteCookie(c *gin.Context) {
    // 删除名为 "my_cookie" 的 Cookie
    c.SetCookie("my_cookie", "", -1, "/", "localhost", false, true)
    
    // 其他逻辑
}

Neste exemplo, usamos  c.SetCookie() o método para excluir o cookie denominado “my_cookie”. Definimos o tempo de expiração do cookie  -1para indicar que o cookie expirou. Em seguida, definimos os outros parâmetros para serem iguais ao cookie original, garantindo que o navegador exclua o cookie correto.

Com esta configuração, o navegador excluirá imediatamente o cookie denominado "my_cookie" quando a resposta for retornada ao cliente.

Deve-se notar que para excluir corretamente um Cookie, você deve garantir que os parâmetros do método SetCookie (como caminho, nome de domínio, Secure, SameSite) são completamente consistentes com os parâmetros usados ​​ao configurar o Cookie. Somente se esses parâmetros corresponderem exatamente o navegador poderá identificar e excluir corretamente o cookie.

Resumindo, para excluir um cookie, defina seu tempo de expiração para um carimbo de data/hora no passado e  c.SetCookie() use os mesmos parâmetros do cookie original no método. Isso notificará o navegador para excluir o cookie imediatamente.

package admins

import (
	"fmt"
	"net/http"
	"os"
	"path"
	"project/models"
	"strconv"

	"github.com/gin-gonic/gin"
)

type AdminControllers struct{}

func (con AdminControllers) Index(c *gin.Context) {
	c.String(200, "admin后管项目")
}

func (con AdminControllers) PageIndex(c *gin.Context) {
	c.HTML(200, "admin/login/index.html", gin.H{
		"title": "admin后管项目",
	})
}

func (con AdminControllers) Login(c *gin.Context) {

	username := c.PostForm("username")
	password := c.PostForm("password")

	c.String(200, "用户名:=%v,密码:=%v \n", username, password)

	// c.HTML(200, "admin/views/index.html", gin.H{
	// 	"title": "viewAdmin页面",
	// })

}

func (con AdminControllers) Register(c *gin.Context) {
	c.HTML(200, "admin/register/index.html", gin.H{
		"title": "注册页面",
	})
}


func (con AdminControllers) Views(c *gin.Context) {

	c.SetCookie("username", "王二妹", 3600, "/", "localhost", false, true)
	c.SetCookie("hobby", "玩游戏,看电视", 5, "/", "localhost", false, true)

	// c.String(200, "Views页面")
	c.HTML(http.StatusOK, "admin/views/index.html", gin.H{
		"title": "views页面",
	})
}

func (con AdminControllers) DeteleCookie(c *gin.Context) {
	username, err := c.Cookie("username")
	// 获取名为 "my_cookie" 的 Cookie
	if err == nil {
		// 找到了名为 "my_cookie" 的 Cookie
		// cookie 变量包含了该 Cookie 的值
		fmt.Printf("username==success===%v \n", username)
	} else {
		// 没有找到名为 "my_cookie" 的 Cookie
		c.String(200, "username==error===%v \n", err.Error())
	}

	c.SetCookie("username", "王二妹", -1, "/", "localhost", false, true)

	c.HTML(http.StatusOK, "admin/views/index.html", gin.H{
		"title":    "views-detelecookie-successfuly",
		"username": username,
	})

}

Requer administrador/visualizações/

 

 Saída terminal:

21:2:49 app         | [GIN] 2023/06/30 - 21:02:49 | 200 |      7.0073ms |             ::1 | GET      "/admin/views"
21:2:55 app         | username==success===王二妹
21:2:55 app         | [GIN] 2023/06/30 - 21:02:55 | 200 |      5.0031ms |             ::1 | GET      "/admin/views/delete"
21:6:43 app         | [GIN] 2023/06/30 - 21:06:43 | 200 |      6.0031ms |             ::1 | GET      "/admin/views"
21:8:38 app         | username==success===王二妹
21:8:38 app         | [GIN] 2023/06/30 - 21:08:38 | 200 |      7.0049ms |             ::1 | GET      "/admin/views/delete"

Aqui você pode expandir a questão do acesso a cookies com nomes de domínio de segundo nível;

No ambiente local localhost, acesse o arquivo host em C:\Windows\System32\drivers\etc e modifique o arquivo de mapeamento;

Arquivo 127.0.0.1.

Aqui você pode ver intuitivamente que, após a modificação, diferentes nomes de domínio de segundo nível também podem acessar o valor do cookie no mesmo host local.

Quanto ao uso de Session, trata-se mais de introdução de pacotes de terceiros ( acesse github.com/gin-contrib/sessions/cookie )

O pacote correspondente precisa ser introduzido no código antes que o middleware de sessão correspondente possa ser registrado no arquivo de entrada principal main();

package main


// 引入但三方包 sessions/cookie
// go get github.com/gin-contrib/sessions/cookie

import (
	"project/routers"

	"github.com/gin-contrib/sessions"
	"github.com/gin-contrib/sessions/cookie" 
	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()

	// Create template for router html template
	r.LoadHTMLGlob("*templates/**/**/*")

	// 主入口文件 注册 session 中间件
	store := cookie.NewStore([]byte("secret")) // 设置 Session 密钥
	r.Use(sessions.Sessions("mysession", store))

	r.GET("/", func(ctx *gin.Context) {
		ctx.JSON(200, gin.H{
			"message": "Hello, world!",
		})
	})

	routers.AdminRoutersInit(r)
	routers.DefaultRoutersInit(r)

	r.Run(":8081")

}

O acima é que o registro foi bem-sucedido e o registro foi bem-sucedido no arquivo de entrada principal main.go. E quanto a outras partes do mundo que são o escopo de uso? (Geralmente usado no controlador correspondente da rota)

Vitrine:

arquivo defaultControllers.go

package defaults

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

type DefaultControllers struct {
}

func (con DefaultControllers) Index(c *gin.Context) {
	// 创建 session 引擎  传入工作对象
	session := sessions.Default(c)
	// 设置过期时间
	session.Options(sessions.Options{
		MaxAge: 3600 * 6, // 6个小时。基础单位秒
	})

	session.Set("username", "xiaoxiao")
	session.Save()

	c.String(200, "default-index.html")
}

func (con DefaultControllers) Add(c *gin.Context) {
	// 获取 session 值 username

	session := sessions.Default(c)

	username := session.Get("username")

	c.String(200, "default==add.html===%v \n", username)

}

O resultado de saída após a execução do código: Defina o valor da sessão nome de usuário ao rotear para /default e defina o valor da sessão ao rotear para /default/add ;

 Pode-se observar que o valor da sessão aqui está criptografado.Se tivermos interesse, podemos verificar o pacote de código-fonte das sessões.

Observação:

1. sessões.Default(c) Aqui está o objeto que gera um middleware de sessões

2. Session.Save() deve estar presente no momento da configuração, caso contrário não terá efeito.

Ao mesmo tempo, ao chamar sessões, o espaço de armazenamento de registro que usamos é o contêiner de cookies. Também podemos usar outros contêineres de espaço de armazenamento, como redis...

O contêiner Redis aqui também é uma boa escolha.

Espero que seja útil para o seu estudo! 

Acho que você gosta

Origin blog.csdn.net/A_LWIEUI_Learn/article/details/131483501
Recomendado
Clasificación