Ответ
В Go, как и в других языках для бэкенда, важно различать два понятия:
- Аутентификация (Authentication, AuthN) — это процесс проверки личности пользователя. Ответ на вопрос: «Кто вы?».
- Авторизация (Authorization, AuthZ) — это процесс проверки прав доступа пользователя к определенным ресурсам. Ответ на вопрос: «Что вам разрешено делать?».
Существует два основных подхода к их реализации:
1. Token-based (на основе токенов)
Это самый популярный stateless-подход для современных API и микросервисов. Наиболее распространенный стандарт — JWT (JSON Web Token).
Процесс:
- Пользователь отправляет логин и пароль.
- Сервер проверяет их, и в случае успеха генерирует JWT, подписывая его секретным ключом.
- Токен возвращается клиенту, который сохраняет его (например, в
localStorage
илиcookie
). - При каждом последующем запросе к защищенным ресурсам клиент отправляет этот токен в заголовке
Authorization: Bearer <token>
. - Сервер проверяет подпись и срок действия токена. Если все в порядке, он извлекает из токена информацию о пользователе (ID, роли) и предоставляет доступ.
Пример с использованием github.com/golang-jwt/jwt/v5
(актуальная библиотека):
import (
"time"
"github.com/golang-jwt/jwt/v5"
)
var jwtKey = []byte("your_secret_key")
type Claims struct {
UserID int64 `json:"user_id"`
jwt.RegisteredClaims
}
// Генерация токена
func generateJWT(userID int64) (string, error) {
expirationTime := time.Now().Add(24 * time.Hour)
claims := &Claims{
UserID: userID,
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(expirationTime),
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString(jwtKey)
}
// Валидация токена
func validateJWT(tokenStr string) (*Claims, error) {
claims := &Claims{}
token, err := jwt.ParseWithClaims(tokenStr, claims, func(token *jwt.Token) (interface{}, error) {
return jwtKey, nil
})
if err != nil {
return nil, err
}
if !token.Valid {
return nil, errors.New("invalid token")
}
return claims, nil
}
2. Session-based (на основе сессий)
Это классический stateful-подход, часто используемый в монолитных веб-приложениях.
Процесс:
- Пользователь отправляет логин и пароль.
- Сервер проверяет их и создает сессию, сохраняя ее ID и данные пользователя у себя (в памяти, Redis, базе данных).
- Клиенту в
cookie
отправляется только идентификатор сессии. - При каждом запросе браузер автоматически отправляет
cookie
с ID сессии. - Сервер находит сессию по ID и получает данные пользователя.
Для этого подхода в Go часто используется пакет gorilla/sessions
.
В современных веб-фреймворках (Gin, Echo, Chi) проверка токенов или сессий обычно выносится в middleware, который защищает определенные эндпоинты.