Як побудувати JWT у Go

  • 5 марта, 14:30
  • 3775
  • 0

Go стає дуже популярним для серверної веб-розробки, а JWT - один з найпопулярніших способів обробки автентифікації по запитам API. У цій статті ми розберемо основи JWT та як реалізувати безпечну стратегію аутентифікації в Go!

Як побудувати JWT у Go

Що таке JWT?

JSON Web Tokens - це відкритий, галузевий стандарт RFC 7519  для надійної передачі даних для аутентифікації в клієнт-серверних додатках.

Токени створюються сервером, підписуються секретним ключем і передаються клієнту, який в подальшому використовує даний токен для підтвердження своєї особи.

 Наприклад, коли користувач заходить на веб-сайт, захищений за допомогою JWT, потік повинен виглядати приблизно так:

  1. Користувач надсилає логін та пароль на сервер
  2. Сервер перевіряє правильність імені користувача та пароль
  3. Сервер створює об'єкт JSON, який виглядає приблизно так: {"username":"wagslane"}
  4. Сервер кодує та підписує об'єкт JSON, створюючи JWT: 

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IndhZ3NsYW5lIn0.ov6d8XtwQoKUwsYahk9UwH333NICElFSs6ag6pINyPQ

  1. Веб-клієнт користувача зберігає JWT для подальшого використання
  2. Коли користувач робить запит до захищеної кінцевої точки, він передає, що JWT знаходиться в заголовку HTTP
  3. Сервер перевіряє підпис JWT, щоб переконатися, що JWT був створений тим же сервером
  4. Сервер зчитує інформацію та дає дозвіл на запит працювати як "wagslane"

Створення JWT

Ми будемо використовувати популярну бібліотеку для роботи з веб-маркерами JSON в Go, jwt-go. Переконайтесь, що у вас код клонований локально:

go get github.com/dgrijalva/jwt-go

Для простоти ми будуємо симетричну схему шифрування. Це означає, що ми припускаємо, що сервер, який створює JWT, також буде єдиним сервером, який буде їх перевіряти.

Спочатку визначте структуру, яка використовуватиметься для представлення заявок для ідентифікації наших користувачів:

type customClaims struct {
    Username string `json:"username"`
    jwt.StandardClaims
}

Структура jwt.StandardClaims містить такі  поля, як термін дії та ім'я емітента. Тепер ми створимо деякі фактичні твердження для користувача, який щойно увійшов у систему:

claims := customClaims{
    Username: username,
    StandardClaims: jwt.StandardClaims{
        ExpiresAt: 15000,
        Issuer:    "nameOfWebsiteHere",
    },
}

Створіть непідписаний токен із тверджень:

token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

Підпишіть токен за допомогою захищеного приватного ключа. На проді переконайтеся, що ви використовуєте справжній закритий ключ, бажано довжиною принаймні 256 біт:

signedToken, err := token.SignedString([]byte("secureSecretText"))

Тепер підписаний токен можна відправити назад клієнту.

Перевірка JWT

Коли клієнт робить запит до захищеної кінцевої точки, ми можемо перевірити, чи є JWT справжнім, виконавши наступні кроки.

* Примітка.  Використання заголовка HTTP-авторизації є ідіоматичним:

Authorization: Bearer {jwt}

Отримавши JWT, підтвердіть дані та підпис, використовуючи той самий приватний ключ:

token, err := jwt.ParseWithClaims(
    jwtFromHeader,
    &customClaims{},
    func(token *jwt.Token) (interface{}, error) {
        return []byte("secureSecretText"), nil 
    },
)

Якщо твердження будуть підроблені, то змінна err  не буде нульовою.

Розбір запиту з токена:

claims, ok := token.Claims.(*customClaims)
if !ok {
    return errors.New("Couldn't parse claims")
}

Перевірка, чи токен не закінчився:

if claims.ExpiresAt < time.Now().UTC().Unix() {
    return errors.New("JWT is expired")
}

Тепер ви знаєте ім’я автентифікованого користувача!

username := claims.Username

Джерело перекладу


0 комментариев
Сортировка:
Добавить комментарий