Single sign-on generic example

In this example we'll show you how you can implement simple single sign-on (SSO) for any kind of PHP-based webpage/application. As a result, users of your php-based webpage/app can access LiveAgent KnowledgeBase or LiveAgent Agent panel directly through a link without going through the generic login process.

Requirements

- Users in php-based page/webapp must have the same e-mail address as their registered username/email in LiveAgent.
- Customers in LiveAgent must be REGISTERED! You can automatically register new users in your customer portal using our APIv3 or manually through your LiveAgent customer portal page.

Integration

Case 1: php-based app / webpage on different domain than LiveAgent KnowledgeBase

Example php-based app domain and path: https://host.lc/www/sso_example/index.php
Example LiveAgent domain and path: https://support.lc/www/git/LiveAgent/LiveAgent/server
 
 
 
 

Case 2: php-based app / webpage on the same domain as the Liveagent KnowledgeBase

Note: this case applies also when web-app is on a different sub-domain than LiveAgent KnowledgeBase. Example webapp.example.com and suport.example.com.
 
Example php-based app domain and path: https://support.lc/www/sso_example/index.php
Example LiveAgent domain and path: https://support.lc/www/git/LiveAgent/LiveAgent/server
 
 

Difference

General principle of both cases are the same - using cookies. But in the 2nd case we can create them directly because we're running our SSO app/page on the same domain as LiveAgent account.

How does it work

It is pretty simple. LiveAgent uses cookies on client side to store customer authentication info. Let's have a look how cookies look like when nobody is logged-in in the KB.
 
 
We have 4 default cookies used by LiveAgent Knowledgebase for storing various application and customer-based info. Now lets login into the Knowledgebase and check the cookies again:
 
 
There was a new cookie created: V_auth. and the content of visitor_la_sid was also changed. It holds the auth token of logged in user. To logout, you need to delete these two cookies or set their validity date to the past. LiveAgent uses the second option to handle user logout.
To make this work from different domain we use a little help from our LiveAgent javascript tracking library. In this lib we have implemented methods for cross-domain login/logout. From the code below you can recognize the proper usage.

The code

Here we have the code of our simple php-based webapp. It supports:
  • login/logout actions and option to set location where user want to log in
  • link to LiveAgent KnowledgeBase (KB).
  • link to LiveAgent AgentPanel (AP)
 
This is the content of index.php file:
<?php
//web-app simple login system
session_start();
$action = @strtolower($_GET['action']);
$loggedIn = isset($_SESSION['userEmail']) && $_SESSION['userEmail'] != null;

const LIVEAGENT_URL = 'https://example.ladesk.com/';                 //put your LiveAgent domain/path here
const SSO_SCRIPT_URL = 'https://host.lc/www/sso_example/index.php'   //enter the URL address of this script
const LIVEAGEN_TRACK_URL = LIVEAGENT_URL . 'scripts/track.js';       //this file is in every LiveAgent installation by default
const LIVEAGENT_API_V1_KEY = '[LIVEAGENT_API_V1_KEY]';               //your LiveAgent API v1 key
const LIVEAGENT_SSO_KEY = '[LIVEAGENT_SSO_KEY]';                     //your Liveagent SSO key
const IS_DIFFERENT_DOMAIN = true;                                    //is your web app on different domain as your Liveagent

function createMagicHash($userEmail, $userAuthToken) {
    return md5($userEmail . $userAuthToken . LIVEAGENT_SSO_KEY);
}

function getUserInfo($visitorEmail, $isRequestToAgentPanel = false) {
    $user = getAgentInfo($visitorEmail);
    if ($user === null && !$isRequestToAgentPanel) {
        $user = getVisitorInfo($visitorEmail);
    }
    return $user;
}

function parseAPIv1Result($result) {
    if (!$result) {
        return null;
    }
    $result = json_decode($result);
    if (!isset($result->response)) {
        return null;
    }
    if (isset($result->response) && isset($result->response->statuscode) && $result->response->statuscode != 0) {
        return null;
    }
    return $result->response;
}

function getAgentInfo($visitorEmail) {
    $ch = curl_init(LIVEAGENT_URL . 'api/?handler=' . 'agents/' . $visitorEmail . '&apikey=' . LIVEAGENT_API_V1_KEY);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    return parseAPIv1Result(curl_exec($ch));
}

function getVisitorInfo($visitorEmail) {
    $ch = curl_init(LIVEAGENT_URL . 'api/?handler=' . 'customers/' . $visitorEmail . '&apikey=' . LIVEAGENT_API_V1_KEY);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    return parseAPIv1Result(curl_exec($ch));
}

?>
<html>
<head>
</head>
<body>
<h1>Hello</h1>
<?php
echo '<a href="'.LIVEAGENT_URL.'" target="_blank">visit KnowledgeBase</a>';
echo '<br>';
echo '<a href="'.LIVEAGENT_URL.'agent" target="_blank">visit AgentPanel</a>';
echo '<script type="text/javascript" id="la_x2s6df8d" src="'.LIVEAGEN_TRACK_URL.'"></script>';
if(!$loggedIn && $action=='login' && @$_POST['userEmail'] != null) {
    $location = @$_POST['location'];
    $loggedIn = login($location);
}
if($loggedIn && $action=='logout' && $_SESSION['userEmail'] != null) {
    if(logout()) {
        $loggedIn = false;
    } else {
        echo '<p>Unable to logout</p>';
    }
}

if(!$loggedIn) {
    if ($action=='login') {
        echo '<p>Unauthorized</p>';
    } else {
        echo '<p>Not logged in.</p>';
    }
    createForm();

}
if($loggedIn) {
    echo '<p>Logged in as '.$_SESSION['userEmail'].' - <a href="'.SSO_SCRIPT_URL.'?action=logout">logout</a></p>';
}

function login($location) {
    $isRequestToAgentPanel = ($location === 'ap');
    $user = getUserInfo($_POST['userEmail'], $isRequestToAgentPanel);
    if ($user) {
        $_SESSION['userEmail'] = $_POST['userEmail'];
        if (IS_DIFFERENT_DOMAIN) {
            differentDomainLogin($user,$location);
        } else {
            sameDomainLogin($user,$location);
        }
        return true;
    }
    return false;
}

function differentDomainLogin($user,$location) {
    $hash = createMagicHash($_SESSION['userEmail'], $user->authtoken);
    echo '<script type="text/javascript">LiveAgentTracker.loginUserOnServer(\''.$hash.'\',\''.$location.'\');</script>';
}

function sameDomainLogin($user,$location) {
    $cookieName = 'V_auth';
    if ($location === 'ap') {
        $cookieName = 'A_auth';
    }
    setcookie($cookieName, $user->authtoken, time() + 60 * 60 * 24 * 356, '/');
}
function logout() {
    $user = getUserInfo($_SESSION['userEmail']);
    if ($user) {
        if (IS_DIFFERENT_DOMAIN) {
            differentDomainLogout($user);
        } else {
            sameDomainLogout();
        }
        $_SESSION['userEmail'] = null;
        return true;
    }
    return false;
}


function differentDomainLogout($user) {
    $hash = createMagicHash($_SESSION['userEmail'], $user->authtoken);
    echo '<script type="text/javascript">document.onload = (function() { LiveAgentTracker.logoutUserOnServer(\'' . $hash . '\');})();</script>';
}

function sameDomainLogout() {
    setcookie("A_auth","", time(), '/');
    setcookie("V_auth","", time(), '/');
    setcookie("visitor_la_sid","", time(), '/');

}

function createForm() {
    echo '<form action="'.SSO_SCRIPT_URL.'?action=login" method="post">';
    echo '<p>Login as user&nbsp;&nbsp;<input name="userEmail" placeholder="User email"></input></p>';
    echo '<p>Location of SSO&nbsp;&nbsp;<select name="location"> <option value="kb">KnowledgeBase</option> <option value="ap">AgentPanel</option> </select></p>';
    echo '</form>';
}
?>
</body>
</html>

In the file above you need to change this constants to match your LiveAgent account: 

  • LIVEAGENT_URL = https://[YOUR_ACCOUNT_NAME].ladesk.com/
  • LIVEAGENT_API_V1_KEY = [YOUR_API_V1_KEY] (LA > Configuration > System > API > Settings for API v1)
  • LIVEAGENT_SSO_KEY = [YOUR_SSO_KEY] (LA > Configuration > System > API > Settings for SSO)
  • IS_DIFFERENT_DOMAIN = [true / false] (is your web app on different domain as your Liveagent)

 

 

Workflow

The webapp page should look like this:

You can choose if you want to log into: KnowledgeBase or AgentPanel, then set User email and submit the login form(user email must be email of Registered Customer or Agent email which exist in your LiveAgent. Registered Customer will be able to only access the KnowledgeBase).

After successfully submitting the form you will see:

Now when you check your browser cookies you should already see the new cookies:

  • For KnowledgeBase login, you will see V_auth cookie
  • For AgentPanel login, you will see A_auth cookie


After you click on link of location you had chosen in form (KnowledgeBase / AgentPanel) and you will be logged in automatically without any additional authentication process.

 

Possible Errors

Unauthorized user email doesn't exist in LA or User has no access to your location:

  • check if user Email is correct
  • check if user is Registered Customer or Agent in LA
  • check your API Keys
Successfully able to submit the form but browser cookie is not set (only in case 1. - LA domain is different as web app):

To see the error you need to open browser dev tools, and open Network section. When you send SSO form, in network section you will see the exact request:

Find request apiAuthUser.php and check response code:

  • 401 - Unauthorized (hash your server send is not valid, check if you set valid api keys) 
  • 409 - Collision (user use 2FA)
  • 400 - User Error (error info is in response of request)