OAuth 2.0 y autorización JWT en C++: en la práctica
\n\nLas aplicaciones web modernas y los microservicios rara vez prescinden de sistemas de autorización. Los dos estándares más populares — OAuth 2.0 para la delegación de acceso y JWT (JSON Web Token) para la transmisión compacta de datos — se han convertido en el estándar de facto de la industria. En este artículo, analizaremos cómo implementar un cliente OAuth 2.0 y trabajar con JWT en C++. Obtendrá ejemplos de código listos para usar y comprenderá cómo integrar estos mecanismos en su proyecto.
\n\n¿Qué son OAuth 2.0 y JWT? Breve resumen
\n\nOAuth 2.0 es un protocolo de autorización que permite a las aplicaciones obtener acceso limitado a los recursos del usuario sin transmitir su nombre de usuario y contraseña. Los participantes principales son: Resource Owner (usuario), Client (nuestra aplicación), Authorization Server (servidor que emite tokens) y Resource Server (servidor que proporciona datos).
\n\nJWT es un formato de token que consta de tres partes: Header (algoritmo de firma), Payload (datos, por ejemplo, ID de usuario o rol) y Signature (firma que protege contra la falsificación). JWT se utiliza a menudo como Bearer-token en OAuth 2.0.
\n\nEn C++ utilizaremos las librerías cpprestsdk (para solicitudes HTTP) y jwt-cpp (para trabajar con JWT). Instálelas a través de vcpkg:
vcpkg install cpprestsdk\nvcpkg install jwt-cpp\n\nImplementación de un cliente OAuth 2.0 en C++
\n\nConsideremos un escenario típico: nuestra aplicación en C++ debe autenticarse a través de Google OAuth 2.0. Para ello necesitamos: registrar la aplicación en Google Cloud Console, obtener un Client ID y un Client Secret, y luego ejecutar el Authorization Code Flow.
\n\nPaso 1: Construcción de la URL de autorización
\n\nEl primer paso es redirigir al usuario a la página de autorización de Google. Construyamos la URL con los parámetros necesarios:
\n\n#include <string>\n#include <cpprest/http_client.h>\n#include <cpprest/uri_builder.h>\n\nusing namespace web;\nusing namespace web::http;\nusing namespace web::http::client;\n\nstd::string BuildAuthorizationUrl(const std::string& client_id,\n const std::string& redirect_uri,\n const std::string& state) {\n uri_builder builder(U("https://accounts.google.com/o/oauth2/v2/auth"));\n builder.append_query(U("client_id"), utility::conversions::to_string_t(client_id));\n builder.append_query(U("redirect_uri"), utility::conversions::to_string_t(redirect_uri));\n builder.append_query(U("response_type"), U("code"));\n builder.append_query(U("scope"), U("openid%20email%20profile"));\n builder.append_query(U("state"), utility::conversions::to_string_t(state));\n builder.append_query(U("access_type"), U("offline"));\n builder.append_query(U("prompt"), U("consent"));\n return utility::conversions::to_utf8string(builder.to_uri().to_string());\n}\n\nPaso 2: Intercambio del código por un token
\n\nDespués de que el usuario confirme el acceso, Google lo redirigirá a nuestro redirect_uri con el parámetro code. Este código debe intercambiarse por un access_token y un refresh_token:
pplx::task<web::json::value> ExchangeCodeForToken(\n const std::string& client_id,\n const std::string& client_secret,\n const std::string& redirect_uri,\n const std::string& code) {\n \n http_client client(U("https://oauth2.googleapis.com/token"));\n \n web::json::value body;\n body[U("code")] = web::json::value::string(utility::conversions::to_string_t(code));\n body[U("client_id")] = web::json::value::string(utility::conversions::to_string_t(client_id));\n body[U("client_secret")] = web::json::value::string(utility::conversions::to_string_t(client_secret));\n body[U("redirect_uri")] = web::json::va