To securely authenticate users with the ContactsManager SDK, you need to generate JWT tokens on your server. This guide explains how to create a secure token generation endpoint.
Install the contactsmanager package for easy token generation.
Copy
pip install contactsmanager
Copy
from contactsmanager import ContactsManagerClient# Initialize the client with your API credentialsclient = ContactsManagerClient( api_key="your-api-key", api_secret="your-api-secret", org_id="your-org-id")# Generate a token for a usertoken_data = client.generate_token( user_id="user-123", device_info={"device_name": "iPhone 15", "os_version": "iOS 17.5"}, expiration_seconds=86400 # 24 hours)# The token to be used in client SDK initializationtoken = token_data["token"]# Example of Flask endpoint that generates tokensfrom flask import Flask, request, jsonifyapp = Flask(__name__)@app.route("/generate-token", methods=["POST"])def token_endpoint(): if request.method != "POST": return jsonify({ "message": "Method not allowed", "success": False }), 405 try: # Parse request body payload = request.json # Validate required fields if not payload.get("userId"): raise ValueError("Missing required field: userId") # Generate token using the SDK token_data = client.generate_token( user_id=payload["userId"], device_info=payload.get("deviceInfo", {}), expiration_seconds=86400 # 24 hours ) # Prepare response response_data = { "token": token_data["token"], "expiresAt": token_data["expires_at"], "message": f"Token generated for user {payload['userId']}", "success": True } return jsonify(response_data), 200 except Exception as e: return jsonify({ "message": f"Error: {str(e)}", "success": False }), 400if __name__ == "__main__": app.run(debug=True)
Install the contactsmanager package for easy token generation.
Copy
pip install contactsmanager
Copy
from contactsmanager import ContactsManagerClient# Initialize the client with your API credentialsclient = ContactsManagerClient( api_key="your-api-key", api_secret="your-api-secret", org_id="your-org-id")# Generate a token for a usertoken_data = client.generate_token( user_id="user-123", device_info={"device_name": "iPhone 15", "os_version": "iOS 17.5"}, expiration_seconds=86400 # 24 hours)# The token to be used in client SDK initializationtoken = token_data["token"]# Example of Flask endpoint that generates tokensfrom flask import Flask, request, jsonifyapp = Flask(__name__)@app.route("/generate-token", methods=["POST"])def token_endpoint(): if request.method != "POST": return jsonify({ "message": "Method not allowed", "success": False }), 405 try: # Parse request body payload = request.json # Validate required fields if not payload.get("userId"): raise ValueError("Missing required field: userId") # Generate token using the SDK token_data = client.generate_token( user_id=payload["userId"], device_info=payload.get("deviceInfo", {}), expiration_seconds=86400 # 24 hours ) # Prepare response response_data = { "token": token_data["token"], "expiresAt": token_data["expires_at"], "message": f"Token generated for user {payload['userId']}", "success": True } return jsonify(response_data), 200 except Exception as e: return jsonify({ "message": f"Error: {str(e)}", "success": False }), 400if __name__ == "__main__": app.run(debug=True)
Install the @contactsmanager/server package for easy token generation.
Copy
npm install @contactsmanager/server
Copy
const { ContactsManagerClient } = require('@contactsmanager/server');// Initialize the client with your API credentialsconst client = new ContactsManagerClient({ apiKey: 'your-api-key', apiSecret: 'your-api-secret', orgId: 'your-org-id'});// Generate a token for a userasync function generateUserToken(userId, deviceInfo = {}) { const tokenData = await client.generateToken({ userId, deviceInfo, expirationSeconds: 86400 // 24 hours }); // The token to be used in client SDK initialization return tokenData.token;}// Example Express.js endpointconst express = require('express');const app = express();app.use(express.json());app.post('/generate-token', async (req, res) => { try { // Parse request body const payload = req.body; // Validate required fields if (!payload.userId) { return res.status(400).json({ message: 'Missing required field: userId', success: false }); } // Generate JWT token using the SDK const tokenData = await client.generateToken({ userId: payload.userId, deviceInfo: payload.deviceInfo || {}, expirationSeconds: 86400 // 24 hours }); // Prepare response const responseData = { token: tokenData.token, expiresAt: tokenData.expiresAt, message: `Token generated for user ${payload.userId}`, success: true }; return res.status(200).json(responseData); } catch (error) { return res.status(400).json({ message: `Error: ${error.message}`, success: false }); }});const PORT = process.env.PORT || 3000;app.listen(PORT, () => { console.log(`Server running on port ${PORT}`);});
The TypeScript (Deno) example can be deployed as a Supabase Edge Function. This serverless approach provides a secure and scalable way to generate tokens without managing traditional server infrastructure.
Copy
import * as jose from "https://deno.land/x/jose@v4.14.4/index.ts";/** * Generates a JWT token for user authentication * @param userId The user's unique identifier * @param deviceInfo Optional device information * @returns A signed JWT token */async function generateToken(userId, deviceInfo = {}) { // Get secrets from environment const apiKey = Deno.env.get("CM_API_KEY"); const apiSecret = Deno.env.get("CM_API_SECRET"); const orgId = Deno.env.get("CM_ORGANIZATION_ID"); if (!apiKey || !apiSecret || !orgId) { throw new Error('Missing required environment variables'); } // Create a JWT payload const now = Math.floor(Date.now() / 1000); const payload = { org_id: orgId, api_key: apiKey, user_id: userId, device_info: deviceInfo, jti: crypto.randomUUID(), iat: now, exp: now + 86400 // Token valid for 24 hours }; // Sign the JWT const secretKey = new TextEncoder().encode(apiSecret); const token = await new jose.SignJWT(payload) .setProtectedHeader({ alg: 'HS256' }) .sign(secretKey); return { token, expires_at: payload.exp };}// Example of a Deno server handlerDeno.serve(async (req) => { // Only allow POST requests if (req.method !== 'POST') { return new Response(JSON.stringify({ message: 'Method not allowed', success: false }), { status: 405, headers: { 'Content-Type': 'application/json' } }); } try { // Parse the request body const payload = await req.json(); // Validate required fields if (!payload.userId) { throw new Error('Missing required field: userId'); } // Generate JWT token const tokenData = await generateToken( payload.userId, payload.deviceInfo || {} ); // Prepare response const responseData = { token: tokenData.token, expires_at: tokenData.expires_at, message: `Token generated for user ${payload.userId}`, success: true }; // Return successful response return new Response(JSON.stringify(responseData), { status: 200, headers: { 'Content-Type': 'application/json' } }); } catch (error) { // Handle errors return new Response(JSON.stringify({ message: `Error: ${error.message}`, success: false }), { status: 400, headers: { 'Content-Type': 'application/json' } }); }});
Once you have the token from your server, you can use it to initialize the ContactsManager SDK:
Copy
// Request token from your serverlet token = await yourApiClient.getToken(for: userId)// Initialize the SDK with the tokentry await ContactsService.shared.initialize( withAPIKey: "your-api-key", token: token, userInfo: userInfo)