Skip to Content
Authgate 1.10.1 is released 🎉
SDKC++

C++ SDK

The Authgate C++ SDK is a header-only client library that you can drop directly into your C++ application.

Installation

  1. Download authgate_api.hpp and authgate_api.cpp from your Authgate purchase
  2. Copy them into your project directory
  3. Include the header in your code

Requirements:

  • C++17 or higher
  • libcurl (for HTTP requests)
  • OpenSSL (for file encryption/decryption)
  • nlohmann/json (for JSON parsing)

Install dependencies:

Ubuntu/Debian:

sudo apt-get install libcurl4-openssl-dev libssl-dev nlohmann-json3-dev

macOS:

brew install curl openssl nlohmann-json

Windows (vcpkg):

vcpkg install curl openssl nlohmann-json

Quick Start

#include "authgate_api.hpp" #include <iostream> int main() { // Initialize the client authgate::AuthgateAPI client( "https://your-authgate.com/api/integration", "your-api-key", "your-api-secret", "your-base64-encryption-key", "your-base64-signing-key", true, // Enable request signing "your-base64-response-signing-key", true // Enable response signing ); try { // Login with username and password auto auth = std::make_unique<authgate::TokenAuthStrategy>( "username", "password" ); client.login(std::move(auth)); // Get app context authgate::AppContext context = client.get_app_context(); std::cout << "Connected to: " << context.application.name << std::endl; // Check membership if (context.user.has_value() && context.user->membership.is_active) { std::cout << "User has active membership!" << std::endl; } } catch (const authgate::AuthenticationError& e) { std::cerr << "Login failed: " << e.what() << std::endl; } catch (const authgate::TimedOutError& e) { std::cerr << "Access paused until: " << e.get_timed_out_until() << std::endl; } catch (const authgate::AuthorizationError& e) { std::cerr << "Access denied: " << e.what() << std::endl; } return 0; }

Compilation

Using g++:

g++ -std=c++17 main.cpp authgate_api.cpp -o myapp -lcurl -lssl -lcrypto

Using CMake:

find_package(CURL REQUIRED) find_package(OpenSSL REQUIRED) find_package(nlohmann_json REQUIRED) add_executable(myapp main.cpp authgate_api.cpp) target_link_libraries(myapp CURL::libcurl OpenSSL::SSL OpenSSL::Crypto nlohmann_json::nlohmann_json)

Authentication

The SDK supports two authentication strategies:

Gets a session token on login and automatically refreshes it when needed.

// Login with username/password auto auth = std::make_unique<authgate::TokenAuthStrategy>( "username", "password" ); client.login(std::move(auth)); // Login with license code auto auth = std::make_unique<authgate::TokenAuthStrategy>( "", "", "LICENSE-CODE" ); client.login(std::move(auth)); // Login with device authentication (if enabled) auto auth = std::make_unique<authgate::TokenAuthStrategy>( "username", "password", "", "device-hardware-id" ); client.login(std::move(auth));

LegacyAuthStrategy

Sends credentials with every request.

auto auth = std::make_unique<authgate::LegacyAuthStrategy>( "username", "password" ); client.login(std::move(auth));

Common Operations

Check Membership Status

authgate::AppContext context = client.get_app_context(); if (context.user.has_value() && context.user->membership.is_active) { // User has access } else { // Show upgrade prompt }

Show Remaining Time

active_until is the UTC time the membership expires. Compare it against context.server_time — not the local clock — so the result is correct even if the device clock is wrong or tampered with.

authgate::AppContext context = client.get_app_context(); const auto& membership = context.user->membership; if (membership.is_lifetime) { std::cout << "Lifetime access" << std::endl; } else if (membership.active_until) { std::cout << "Active until: " << *membership.active_until << " (server time: " << context.server_time << ")" << std::endl; }

Activate a License

try { authgate::MembershipLicenseAdjustment adjustment = client.activate_license("LICENSE-CODE", "username", "password"); if (adjustment.grants_lifetime_access) { std::cout << "Lifetime license activated!" << std::endl; } else if (adjustment.minutes.has_value()) { std::cout << "Added " << *adjustment.minutes << " minutes" << std::endl; } } catch (const authgate::ValidationError& e) { std::cerr << "Invalid license code" << std::endl; }

Download Files

// Download and decrypt a file std::vector<uint8_t> file_data = client.download_file( "file-uuid", true, // decrypt "config.json" // optional: save to disk ); std::cout << "Downloaded " << file_data.size() << " bytes" << std::endl;

Access Server Variables

authgate::AppContext context = client.get_app_context(); for (const auto& variable : context.application.variables) { std::cout << variable.name << ": " << variable.value << std::endl; }

Access Announcements

The app context contains announcements that are currently published and visible. Content is provided as HTML for your application to display.

authgate::AppContext context = client.get_app_context(); for (const auto& announcement : context.announcements) { std::cout << announcement.title << std::endl; std::cout << announcement.content_html << std::endl; }

Call get_app_context() again to refresh the list. See Announcements for publication and scheduling options.

User Variables

Store and retrieve per-user data that syncs across devices:

// Set a user variable (creates if doesn't exist) client.set_user_variable("theme", "dark"); // Get a single user variable std::string theme = client.get_user_variable("theme"); // List all user variables std::vector<authgate::UserVariable> vars = client.get_user_variables(); for (const auto& var : vars) { std::cout << var.name << ": " << var.value << std::endl; }

Error Handling

The SDK uses exception classes for different error types:

try { client.get_app_context(); } catch (const authgate::AuthenticationError& e) { std::cerr << "Authentication failed - wrong credentials or not logged in" << std::endl; } catch (const authgate::TimedOutError& e) { std::cerr << "Access paused until " << e.get_timed_out_until() << std::endl; if (!e.get_reason().empty()) { std::cerr << "Reason: " << e.get_reason() << std::endl; } } catch (const authgate::AuthorizationError& e) { // Check specific error code std::string error_code = e.get_error_code(); if (error_code == "BANNED") { std::cerr << "Account banned" << std::endl; } else if (error_code == "INACTIVE_MEMBERSHIP") { std::cerr << "Membership expired" << std::endl; } else { std::cerr << "Access denied" << std::endl; } } catch (const authgate::ValidationError& e) { // Get field-specific errors auto errors = e.get_validation_errors(); for (const auto& [field, message] : errors) { std::cerr << field << ": " << message << std::endl; } } catch (const authgate::NetworkError& e) { std::cerr << "Connection failed" << std::endl; } catch (const authgate::AuthgateApiError& e) { std::cerr << "API error: " << e.what() << std::endl; }

Catch TimedOutError before AuthorizationError. It provides the ISO 8601 expiry time and the optional reason entered by the admin.

Device Authentication

If device authentication is enabled on your application, you must provide a hardware_id when logging in or signing up:

During Login:

// Generate a unique hardware ID for this device // (e.g., MAC address, CPU serial, or composite hash) std::string hardware_id = "00:1B:44:11:3A:B7"; auto auth = std::make_unique<authgate::TokenAuthStrategy>( "username", "password", "", hardware_id ); client.login(std::move(auth));

During Sign-Up:

// Sign up with username/password and register device std::string hardware_id = "00:1B:44:11:3A:B7"; authgate::User user = client.sign_up("username", "password", hardware_id); // Sign up with license code and register device authgate::User user = client.sign_up_with_license_code("LICENSE-CODE", hardware_id);

API Reference

AuthgateAPI Class

Constructor:

AuthgateAPI( const std::string& base_url, // Your Authgate API URL const std::string& api_key, // Application API key const std::string& api_secret, // Application API secret const std::string& files_encryption_key, // Base64 encryption key const std::string& request_signing_key, // Base64 signing key bool request_signing_enabled, const std::string& response_signing_key, // Base64 response signing key bool response_signing_enabled, bool verify_ssl = true // Set false for self-signed certs )

Methods:

  • void login(std::unique_ptr<AuthStrategy> auth_strategy) - Authenticate user
  • void logout() - Clear authentication
  • AppContext get_app_context() - Get application, announcements, and user info
  • User sign_up(const std::string& username, const std::string& password, const std::string& hardware_id = "") - Create account
  • User sign_up_with_license_code(const std::string& code, const std::string& hardware_id = "") - Create account with license
  • MembershipLicenseAdjustment activate_license(...) - Activate a license
  • std::vector<uint8_t> download_file(...) - Download a file
  • std::string get_user_variable(const std::string& name) - Get a user variable
  • void set_user_variable(const std::string& name, const std::string& value) - Set a user variable
  • std::vector<UserVariable> get_user_variables() - List all user variables

Data Structures

struct Variable { std::string name; std::string value; }; struct File { std::string id; // UUID std::string name; std::string mime_type; bool is_encrypted; }; struct Application { std::string id; std::string name; std::vector<Variable> variables; std::vector<File> files; }; struct Membership { bool is_active; bool is_lifetime; std::optional<std::string> active_until; // ISO 8601 UTC, empty if lifetime/none }; struct User { std::string id; std::string username; Membership membership; }; struct AppContext { Application application; std::optional<User> user; std::string server_time; // ISO 8601 UTC, anchor for active_until };

Complete Example

#include "authgate_api.hpp" #include <iostream> int main() { authgate::AuthgateAPI client( "https://auth.myapp.com/api/integration", "api-key", "api-secret", "encryption-key", "signing-key", true, "response-signing-key", true ); try { // Login auto auth = std::make_unique<authgate::TokenAuthStrategy>( "username", "password" ); client.login(std::move(auth)); // Check access authgate::AppContext context = client.get_app_context(); if (context.user.has_value() && context.user->membership.is_active) { std::cout << "Welcome to the app!" << std::endl; // Download config file if available if (!context.application.files.empty()) { client.download_file( context.application.files[0].id, true, "config.json" ); } } else { std::cout << "Please purchase a license" << std::endl; } } catch (const authgate::AuthenticationError& e) { std::cerr << "Login failed - wrong credentials" << std::endl; } catch (const authgate::AuthorizationError& e) { std::cerr << "Access denied - inactive membership" << std::endl; } catch (const authgate::AuthgateApiError& e) { std::cerr << "Error: " << e.what() << std::endl; } return 0; }
Last updated on