Server-Side Token Generation

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.

Authentication Flow

  1. Your app requests a token from your server
  2. Your server generates a signed JWT token using your API secret
  3. The server returns the token to your app
  4. Your app initializes the ContactsManager SDK with the token

This approach keeps your API secret secure by never exposing it in client code.

Token Structure

The JWT token contains the following claims:

ClaimDescription
org_idYour organization ID
api_keyYour ContactsManager API key
user_idThe unique identifier for the user
jtiA unique token identifier (UUID)
iatToken issued at timestamp
expToken expiration timestamp

Implementation Examples

Install the contactsmanager package for easy token generation.

pip install contactsmanager
from contactsmanager import ContactsManagerClient

# Initialize the client with your API credentials
client = ContactsManagerClient(
    api_key="your-api-key",
    api_secret="your-api-secret",
    org_id="your-org-id"
)

# Generate a token for a user
token_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 initialization
token = token_data["token"]

# Example of Flask endpoint that generates tokens
from flask import Flask, request, jsonify

app = 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
        }), 400

if __name__ == "__main__":
    app.run(debug=True)

Environment Variables

For all implementations, set these environment variables on your server:

VariableDescription
CM_API_KEYYour ContactsManager API key
CM_API_SECRETYour ContactsManager API secret
CM_ORGANIZATION_IDYour organization ID

Security Considerations

  1. Keep Your API Secret Secure: Never expose your API secret in client-side code
  2. Set a Reasonable Expiration Time: Balance security and user experience
  3. Use HTTPS: Always use HTTPS for all API endpoints
  4. Validate User ID: Ensure the user ID is valid before generating a token
  5. Implement Rate Limiting: Protect your token endpoint from abuse

Using the Token in your App

Once you have the token from your server, you can use it to initialize the ContactsManager SDK:

// Request token from your server
let token = await yourApiClient.getToken(for: userId)

// Initialize the SDK with the token
try await ContactsService.shared.initialize(
    withAPIKey: "your-api-key",
    token: token,
    userInfo: userInfo
)