Реализация OAuth 2.0 и JWT авторизации на C++ для начинающих

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение в OAuth 2.0 и JWT на C++

В современной веб-разработке безопасность и управление доступом — критически важные аспекты. OAuth 2.0 и JWT (JSON Web Tokens) стали стандартом де-факто для реализации авторизации в API и веб-приложениях. Несмотря на то, что эти технологии чаще ассоциируются с JavaScript, Python или Java, C++ также предоставляет мощные инструменты для их реализации.

В этой статье мы разберем, как работают OAuth 2.0 и JWT, и покажем практические примеры их реализации на C++. Материал ориентирован на начинающих разработчиков, знакомых с основами C++ и сетевым программированием.

Что такое OAuth 2.0?

OAuth 2.0 — это протокол авторизации, который позволяет приложениям получать ограниченный доступ к ресурсам пользователя без передачи его учетных данных (логина и пароля). Вместо этого используются токены доступа. Основные роли в OAuth 2.0:

  • Resource Owner (Владелец ресурса) — пользователь, которому принадлежат данные.
  • Client (Клиент) — приложение, запрашивающее доступ.
  • Authorization Server (Сервер авторизации) — выдает токены после успешной аутентификации.
  • Resource Server (Сервер ресурсов) — API, защищенный токенами.

Что такое JWT?

JWT (JSON Web Token) — это компактный формат токена, который содержит JSON-объект с данными (claims) и подписан для проверки целостности. Структура JWT состоит из трех частей, разделенных точками:

  • Header (Заголовок) — содержит тип токена и алгоритм подписи (например, HS256 или RS256).
  • Payload (Полезная нагрузка) — содержит данные (например, ID пользователя, срок действия).
  • Signature (Подпись) — создается путем хеширования header + payload с использованием секретного ключа.

Преимущество JWT в том, что он самодостаточен: сервер ресурсов может проверить токен без обращения к серверу авторизации, что ускоряет работу.

Основная часть: Реализация на C++

1. Библиотеки и подготовка окружения

Для работы с OAuth 2.0 и JWT на C++ нам понадобятся следующие библиотеки:

  • cURL (libcurl) — для HTTP-запросов к серверу авторизации.
  • nlohmann/json — для работы с JSON.
  • jwt-cpp — для создания и проверки JWT токенов.
  • OpenSSL — для криптографических операций (подписи и хеширования).

Установка через vcpkg (рекомендуется):

vcpkg install curl jsoncpp jwt-cpp openssl

Пример CMakeLists.txt:

cmake_minimum_required(VERSION 3.15)
project(OAuthJWTExample)

find_package(CURL REQUIRED)
find_package(nlohmann_json REQUIRED)
find_package(jwt-cpp REQUIRED)
find_package(OpenSSL REQUIRED)

add_executable(main main.cpp)
target_link_libraries(main
    CURL::libcurl
    nlohmann_json::nlohmann_json
    jwt-cpp::jwt-cpp
    OpenSSL::SSL
    OpenSSL::Crypto
)

2. Реализация OAuth 2.0 Authorization Code Flow

Рассмотрим самый распространенный поток — Authorization Code Flow. Клиент получает код авторизации от пользователя, а затем обменивает его на токен доступа.

Шаг 1: Перенаправление пользователя на сервер авторизации (упрощенный пример):

#include <iostream>
#include <string>

std::string buildAuthUrl(const std::string& clientId, 
                         const std::string& redirectUri) {
    return "https://auth.example.com/authorize?"
           "response_type=code&"
           "client_id=" + clientId + "&"
           "redirect_uri=" + redirectUri + "&"
           "scope=openid+profile";
}

int main() {
    std::string clientId = "your_client_id";
    std::string redirectUri = "http://localhost:8080/callback";
    std::string authUrl = buildAuthUrl(clientId, redirectUri);
    std::cout << "Redirect user to: " << authUrl << std::endl;
    return 0;
}

Шаг 2: Обмен кода на токен доступа (используем libcurl):

#include <curl/curl.h>
#include <nlohmann/json.hpp>
#include <string>

using json = nlohmann::json;

size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* output) {
    size_t totalSize = size * nmemb;
    output->append((char*)contents, totalSize);
    return totalSize;
}

std::string exchangeCodeForToken(const std::string& code,
                                  const std::string& clientId,
                                  const std::string& clientSecret,
                                  const std::string& redirectUri) {
    CURL* curl = curl_easy_init();
    std::string response;

    if (curl) {
        std::string postData = "grant_type=authorization_code&"
                               "code=" + code + "&"
                               "client_id=" + clientId + "&"
                               "client_secret=" + clientSecret + "&"
                               "redirect_uri=" + redirectUri;

        curl_easy_setopt(curl, CURLOPT_URL, "https://auth.example.com/token");
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData.c_str());
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);

        CURLcode res = curl_easy_perform(curl);
        curl_easy_cleanup(curl);

        if (res != CURLE_OK) {
            throw std::runtime_error("cURL error: " + std::string(curl_easy_strerror(res)));
        }
    }

    json parsed = json::parse(response);
    return parsed["access_token"];
}

3. Создание и проверка JWT токенов

После получения токена доступа (который часто является JWT), его можно проверить на стороне сервера ресурсов. Используем библиотеку jwt-cpp.

Пример создания JWT:

#include <jwt-cpp/jwt                

Блоги

Рекомендаций по книгам