Implementando JWT no Gin Framework: Geração de Tokens e Autenticação com Middleware

Implementando JWT no Gin Framework: Geração de Tokens e Autenticação com Middleware

O JWT (JSON Web Token) é uma tecnologia amplamente utilizada para autenticação em aplicações web. O projeto está disponível no GitHub:

https://github.com/dgrijalva/jwt-go/

Um token JWT é composto por três partes separadas por pontos: o cabeçalho (header), a carga útil (payload) e a assinatura. Por exemplo:

//eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjYsImV4cCI6MTYzNzY2Nzk5OCwiaWF0IjoxNjM3MDYzMTk4LCJpc3MiOiJjaGVuZ3FpYW5nIiwic3ViIjoidXNlciB0b2tlbiJ9.nt8K7vxrAT4XXzh0RbtFveQCyt7J4r1XZnVgDNSVjkQ

Você pode decodificar cada parte usando base64. Por exemplo, para decodificar o cabeçalho:

echo eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 | base64 -D

Configuração JWT: utils/jwt.go

package utils

import (
	"github.com/dgrijalva/jwt-go"
	"meuProjeto/modelos"
	"time"
)

// Chave secreta para assinar os tokens
var segredoJWT = []byte("minha-chave-secreta-2023")

type DadosToken struct {
	IDUsuario uint
	jwt.StandardClaims
}

// Gera um token após o login bem-sucedido
func GerarToken(usuario modelos.Usuario) (string, error) {
	tempoExpiracao := time.Now().Add(7 * 24 * time.Hour) // Token válido por 7 dias
	
	dados := &DadosToken{
		IDUsuario: usuario.ID,
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: tempoExpiracao.Unix(),
			IssuedAt:  time.Now().Unix(),
			Issuer:    "meu-sistema",
			Subject:   "autenticacao-usuario",
		},
	}

	token := jwt.NewWithClaims(jwt.SigningMethodHS256, dados)
	tokenString, erro := token.SignedString(segredoJWT)

	if erro != nil {
		return "", erro
	}
	
	return tokenString, nil
}

// Analisa o token recebido do frontend
func ValidarToken(tokenString string) (*jwt.Token, *DadosToken, error) {
	dados := &DadosToken{}
	token, erro := jwt.ParseWithClaims(tokenString, dados, func(token *jwt.Token) (interface{}, error) {
		return segredoJWT, nil
	})
	return token, dados, erro
}

Middleware para verificação de atuenticação

package middlewares

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"strings"
	"meuProjeto/utils"
	"meuProjeto/modelos"
)

// Middleware que verifica o token de autorização no cabeçalho da requisição
func Autenticacao() gin.HandlerFunc {
	return func(c *gin.Context) {
		// Obtém o token do cabeçalho Authorization
		cabecalhoAutorizacao := c.GetHeader("Authorization")

		fmt.Print("Token recebido:", cabecalhoAutorizacao)

		// Verifica se o token existe e segue o formato "Bearer <token>"
		if cabecalhoAutorizacao == "" || !strings.HasPrefix(cabecalhoAutorizacao, "Bearer ") {
			c.JSON(401, gin.H{
				"dados": gin.H{},
				"meta": gin.H{
					"mensagem": "Acesso não autorizado",
					"codigo":   401,
				},
			})
			c.Abort()
			return
		}

		// Extrai o token removendo o prefixo "Bearer "
		tokenString := cabecalhoAutorizacao[7:]
		
		// Valida o token
		token, dadosToken, erro := utils.ValidarToken(tokenString)
		if erro != nil || !token.Valid {
			c.JSON(401, gin.H{
				"dados": gin.H{},
				"meta": gin.H{
					"mensagem": "Token inválido",
					"codigo":   401,
				},
			})
			c.Abort()
			return
		}

		// Token válido, obtém o ID do usuário
		idUsuario := dadosToken.IDUsuario
		var usuario modelos.Usuario
		// Busca o usuário no banco de dados
		utils.DB.First(&usuario, idUsuario)

		// Verifica se o usuário existe
		if usuario.ID == 0 {
			c.JSON(401, gin.H{
				"dados": gin.H{},
				"meta": gin.H{
					"mensagem": "Usuário não encontrado",
					"codigo":   401,
				},
			})
			c.Abort()
			return
		}

		// Armazena as informações do usuário no contexto da requisição
		c.Set("usuario", usuario)
		
		// Continua o processamento da requisição
		c.Next()
	}
}

Este middleware deve ser aplicaod às rotas que exigem autenticação. Ele verifica a presença e validade do token no cabeçalho Authorization, e se tudo estiver correto, permite o acesso à rota protegida.

Tags: gin Golang jwt autenticacao middleware

Publicado em 5-30 17:48 por Thomas