Introduction to OAuth 2.0 and JWT in C++
\n\nModern web applications and APIs rarely do without authorization systems. The two most popular standards — OAuth 2.0 and JWT (JSON Web Token) — have become the security foundation for millions of services. In this article, we will break down how to implement basic OAuth 2.0 authorization with JWT tokens in C++. You will learn how these protocols work and see ready-made code examples that can be adapted for your project.
\n\nThe article is aimed at beginner developers who are already familiar with the basics of C++ (classes, functions, networking) and want to add secure authorization to their applications. We will not use third-party libraries for the HTTP server — all examples will be in pure C++ with minimal dependencies.
\n\nWhat is OAuth 2.0 and why is it needed?
\n\nOAuth 2.0 is an authorization protocol that allows applications to obtain limited access to user resources without sharing their password. Imagine you want to give an application access to your photos on a server. Instead of entering your login and password, you go through an Authorization Server, which issues a temporary token. The application uses this token to access the resources.
\n\nThe main roles in OAuth 2.0:
\n- \n
- Resource Owner — the user, the data owner. \n
- Client — the application requesting access. \n
- Authorization Server — the server that issues tokens after authentication. \n
- Resource Server — the server storing protected data (e.g., an API). \n
In C++, we will implement a simplified version of the Authorization Server and Resource Server, using JWT as the access token.
\n\nJWT: Structure and How It Works
\n\nJWT (JSON Web Token) is a compact and self-contained way to transmit information between parties as a JSON object. The token consists of three parts, separated by dots:
\n\nheader.payload.signature\n\nHeader contains the token type and the signing algorithm (usually HMAC SHA256 or RSA). Payload is the useful data: user ID, token lifetime, roles, etc. Signature is the signature that verifies data integrity.
\n\nExample of creating a JWT in C++ without libraries (simplified):
\n\n#include <iostream>\n#include <sstream>\n#include <vector>\n#include <openssl/sha.h>\n#include <openssl/hmac.h>\n\nstd::string base64_encode(const std::string &input) {\n // Simplified Base64 implementation (for example)\n static const char* lookup = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";\n std::string result;\n // ... encoding code ...\n return result;\n}\n\nstd::string create_jwt(const std::string &payload, const std::string &secret) {\n std::string header = R"({"alg":"HS256","typ":"JWT"})";\n std::string header_b64 = base64_encode(header);\n std::string payload_b64 = base64_encode(payload);\n std::string data = header_b64 + "." + payload_b64;\n \n unsigned char* sig = HMAC(EVP_sha256(), secret.c_str(), secret.length(), \n (unsigned char*)data.c_str(), data.length(), NULL, NULL);\n std::string sig_b64 = base64_encode(std::string((char*)sig, 32));\n \n return data + "." + sig_b64;\n}\n\nint main() {\n std::string payload = R"({"user_id":123,"role":"admin","exp":1700000000})";\n std::string token = create_jwt(payload, "my_secret_key");\n std::cout << "JWT: " << token << std::endl;\n return 0;\n}\n\nThis code creates a JWT with an HS256 header and payload. In real projects, use proven libraries like jwt-cpp or libjwt, but for understanding the essence, this approach works.