Introdução: por que OAuth 2.0 e JWT em Go?
\nAplicações web e APIs modernas raramente funcionam sem um sistema de autorização. Se você está programando em Go (Golang) e deseja proteger seus endpoints, precisa entender duas tecnologias-chave: OAuth 2.0 (protocolo de delegação de acesso) e JWT (JSON Web Token — formato compacto de token).
\nNeste artigo, vamos abordar como implementar autorização segura em Go do zero. Você aprenderá:
\n- \n
- A diferença entre OAuth 2.0 e JWT e como eles funcionam juntos. \n
- Como gerar e verificar tokens JWT em Go. \n
- Como construir uma autorização OAuth 2.0 mínima (fluxo Client Credentials). \n
- Como proteger uma REST API com middleware. \n
O artigo é voltado para desenvolvedores iniciantes que já conhecem os fundamentos de Go e servidores HTTP.
\n\nFundamentos: OAuth 2.0 e JWT — não são a mesma coisa
\nMuitos iniciantes confundem esses conceitos. Vamos esclarecer isso de uma vez.
\n\nO que é OAuth 2.0?
\nOAuth 2.0 é um protocolo de autorização que permite que um serviço (cliente) obtenha acesso limitado aos recursos de outro serviço (servidor) em nome de um usuário. Imagine que você deseja fazer login em um site usando o Google. O site não obtém sua senha — ele recebe do Google um token temporário que dá acesso apenas ao seu e-mail (e com seu consentimento).
\nOs principais papéis no OAuth 2.0:
\n- \n
- Resource Owner — proprietário dos dados (geralmente o usuário). \n
- Client — aplicativo que deseja obter acesso. \n
- Authorization Server — servidor que emite tokens após verificação. \n
- Resource Server — servidor que armazena dados protegidos e verifica tokens. \n
O que é JWT?
\nJWT (JSON Web Token) é o formato do token em si. É uma string composta por três partes separadas por pontos: header.payload.signature. O JWT pode conter quaisquer dados (por exemplo, ID do usuário, função, data de expiração) e é assinado com uma chave secreta para evitar falsificação.
O OAuth 2.0 não está vinculado ao JWT — o token pode ser qualquer string. No entanto, na prática, o JWT é o mais usado porque é autossuficiente: o servidor não precisa armazenar sessões no banco de dados, todas as informações podem ser verificadas em tempo real.
\n\nImplementação de JWT em Go: geração e verificação de tokens
\nVamos começar com a prática. Para trabalhar com JWT em Go, usaremos a biblioteca golang-jwt/jwt/v5. Instale-a:
go get github.com/golang-jwt/jwt/v5\n\nGeração de Access Token
\nVamos criar uma função que recebe o ID do usuário e retorna um token JWT assinado com tempo de vida de 1 hora.
\npackage main\n\nimport (\n "time"\n "github.com/golang-jwt/jwt/v5"\n)\n\nvar jwtSecret = []byte("sua-chave-secreta") // Em produção, armazene no .env!\n\ntype Claims struct {\n UserID uint `json:"user_id"`\n jwt.RegisteredClaims\n}\n\nfunc GenerateAccessToken(userID uint) (string, error) {\n claims := Claims{\n UserID: userID,\n RegisteredClaims: jwt.RegisteredClaims{\n ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour)),\n IssuedAt: jwt.NewNumericDate(time.Now()),\n Issuer: "my-app",\n },\n }\n token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)\n return token.SignedString(jwtSecret)\n}\n\nVerificação e parsing de JWT
\nAgora vamos escrever um middleware que verifica o token do cabeçalho Authorization: Bearer <token>.
func ValidateToken(tokenString string) (*Claims, error) {\n token, err := jwt.ParseWithClaims(tokenString, &Claims{}, func(token *jwt.Token) (interface{}, error) {\n // Verifica se o método de assinatura está correto\n