Example: C++
How to generate Vivox access tokens using C++ code.
Read time 2 minutesLast updated 20 hours ago
The following code is an example of how to generate access tokens in C++.
/** Vivox Token Generation Example - C++* Note: This example uses C++11, and is written to not use external libraries to demonstrate the token generation process.* However, because HMACSHA256 is required, this example uses OpenSSL 1.1.0+.**/#include <openssl/sha.h>#include <openssl/evp.h>#include <openssl/hmac.h>#include <iostream>#include <iomanip>#include <sstream>#include <string>using namespace std;typedef unsigned char uchar;static const string b = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_+/";/** You can use Base64URL encoding or Base64 and URL encoding libraries in place of this implementation* Note: Any trailing ='s must be removed from the encoded string.*/static string base64_encode(const string &in){ string out; int val = 0, valb = -6; for (const char c : in) { val = (val << 8) + static_cast<unsigned char>(c); valb += 8; while (valb >= 0) { out.push_back(b[(val >> valb) & 0x3F]); valb -= 6; } } if (valb >- 6) out.push_back(b[((val << 8) >> (valb + 8))& 0x3F]); return out;}#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)static HMAC_CTX *HMAC_CTX_new(void){ HMAC_CTX *ctx = static_cast<HMAC_CTX *>(OPENSSL_malloc(sizeof(*ctx))); if (ctx != nullptr) { HMAC_CTX_init(ctx); } return ctx;}static void HMAC_CTX_free(HMAC_CTX *ctx){ if (ctx != nullptr) { HMAC_CTX_cleanup(ctx); OPENSSL_free(ctx); }}#endif/** Uses OpenSSL 1.1.0+ to encode data with a secret using HMAC SHA-256*/string hmac(string key, string msg){ unsigned char hash[32]; HMAC_CTX *hmac = HMAC_CTX_new(); HMAC_Init_ex(hmac, &key[0], static_cast<int>(key.length()), EVP_sha256(), nullptr); HMAC_Update(hmac, reinterpret_cast<const unsigned char *>(&msg[0]), msg.length()); unsigned int len = 32; HMAC_Final(hmac, hash, &len); HMAC_CTX_free(hmac); stringstream ss; ss << setfill('0'); for (unsigned int i = 0; i < len; i++) { ss << hash[i]; } return ss.str();}static string vx_generate_token(const string &key, const string &issuer, int exp, const string &vxa, int vxi, const string &f, const string &t){ // Header is static - base64url encoded {} string header = base64_encode("{}"); // Can also be defined as a constant "e30" // Create payload and base64 encode stringstream ss; ss << "{ \"iss\": \"" << issuer << "\","; ss << "\"exp\": " << exp << ","; ss << "\"vxa\": \"" << vxa << "\","; ss << "\"vxi\": " << vxi << ","; ss << "\"t\": \"" << t << "\","; ss << "\"f\": \"" << f << "\" }"; string payload = base64_encode(ss.str()); // Join segments to prepare for signing string to_sign = header + "." + payload; // Sign token with key and HMACSHA256, then base64 encode string signed_payload = base64_encode(hmac(key, to_sign)); // Combine header and payload with signature return to_sign + "." + signed_payload;}int main(){ string token = vx_generate_token("secret", "issuer", 1559359105, "join", 123456, "sip:.username.@domain.vivox.com", "sip:confctl-g-channelname@domain.vivox.com"); cout << token << endl; return 0;}