External username and password check of Contact in Sugar

Hi,

We use Sugar CRM as our members platform. Now I want to enable members(contacts) to login to our members hub on our website by using a login that checks the username (email address) and password stored within our Sugar CRM contacts. How do I go about this? Tips/ help is more than welcome. Thanks

  • Hi Rick,

    Do your members already have logins for accessing the Members Hub? If so, are you looking to keep the user database for the members hub in sync with the Contact info in Sugar?

  • I did that some years ago for a member platform. Just used the portal_user and portal_password fields of Contacts module but you can also create your wn userid/password fields to save the credentials. If you use the email you should check for duplicates before save and copy email1  to the userid field.

    The members platform used one single Sugar User to login via REST and then checked the userid/password against the Contacts module. If the combination was found the member was authenticated.

    Harald Kuske
    Principal Solution Architect – Professional Services, EMEA
    hkuske@sugarcrm.com
    SugarCRM Deutschland GmbH

  • Hi thanks for your reply,

    Our members have login details stored within Sugar contacts 

  • Hi Harald,

    That's what I'm after, login from our website -- check userid and pw from sugar contacts if true member gets onto our member section on our website. (btw. we already have eliminated email dubs in our sugar)

    Rick

  • The attached php file is a very  simple and unsecure example just using text search on text fields member_userid_c and member_password_c. to show a prinicipal solution. For a secure productive solution you should create an own API login call which decodes the password from a password field e.g. with BLOWFISH encryption.

    member_login.php
    <?php
    $member_found = false;
    $first_name = "";
    $last_name = "";
    ?>
    <html>
    <head>
    <title>Test</title>
    </head>
    <body>
    <form name="test_member" action="" method="post">
    Userid: <input name="userid" type="text" value="" /><br/>
    Password: <input name="password" type="text" value="" /><br/>
    <input name="button" type="submit" value="Login" /><br/>
    </form>
    <?php
    
    if (($_REQUEST["userid"] != "") && ($_REQUEST["password"] != "")) {
    	$base_url = "https://localhost/sugarent1010/rest/v10";
    	$username = "admin";  // user who is admin
    	$password = "****";  // password
    	$platform = "mobile"; // not base to prevent kicking out of the desktop app
    	
    	// Login - POST /oauth2/token
    	$login_url = $base_url . "/oauth2/token";
    	$logout_url = $base_url . "/oauth2/logout";										   
    	
    	$oauth2_token_arguments = array(
    		"grant_type" => "password",
    		"client_id" => "sugar",
    		"client_secret" => "",
    		"username" => $username,
    		"password" => $password,
    		"platform" => $platform
    	);
    	
    	// Login
    	$oauth2_token_response = call($login_url, '', 'POST', $oauth2_token_arguments);
    	$DEBUG .= "## TOKEN RESPONSE: ".print_r($oauth2_token_response,true)." ##</hr>\n";
    	echo $DEBUG; $DEBUG="";
    	if ($oauth2_token_response->access_token == "") die("No Login");
    	
    	// READ Contact
    	$url = $base_url . '/Contacts';
    	$contacts_arguments = array(
    		"filter" => array(
    			array(
    				'$and' => array(
    					array(
    						'member_userid_c' => $_REQUEST['userid'],					   
    						'member_password_c' => $_REQUEST['password'],		
    					)
    				)
    			)
    		),
    		"fields" => "id,first_name,last_name",
    	);
    	$DEBUG .= "## SEARCH contacts: ".print_r($contacts_arguments,true)." ##</br>\n";
    	$contacts_response = call($url, $oauth2_token_response->access_token, 'GET', $contacts_arguments);
    	$DEBUG .= "## SEARCH RESULT: ".print_r($contacts_response,true)." ##</br>\n";
    	
    	if (count($contacts_response->records) == 1) {
    		
    		$member_found = true;
    		$first_name = $contacts_response->records[0]->first_name;
    		$last_name = $contacts_response->records[0]->last_name;
    		
    	} else {
    		echo $DEBUG; $DEBUG="";
    		die("ERROR - Members found: ".count($contacts_response->records));
    	}
    		
    	// logout to clean up
    	call($logout_url, '', 'POST', $oauth2_token_arguments);
    }
    
    echo $DEBUG; $DEBUG="";
    
    ////////////////////////////////////////////////////////////////////
    // END OF MAIN
    ////////////////////////////////////////////////////////////////////
    /**
     * Generic function to make cURL request.
     * @param $url - The URL route to use.
     * @param string $oauthtoken - The oauth token.
     * @param string $type - GET, POST, PUT, DELETE. Defaults to GET.
     * @param array $arguments - Endpoint arguments.
     * @param array $encodeData - Whether or not to JSON encode the data.
     * @param array $returnHeaders - Whether or not to return the headers.
     * @param array $filenHeader - Whether or not to upload a file
     * @return mixed
     */
    function call(
        $url,
        $oauthtoken='',
        $type='GET',
        $arguments=array(),
        $encodeData=true,
        $returnHeaders=false,
    	$fileHeader=false
    )
    {
        $type = strtoupper($type);
    
        if ($type == 'GET')
        {
            $url .= "?" . http_build_query($arguments);
        }
    
        $curl_request = curl_init($url);
    
        if ($type == 'POST')
        {
            curl_setopt($curl_request, CURLOPT_POST, 1);
        }
        elseif ($type == 'PUT')
        {
            curl_setopt($curl_request, CURLOPT_CUSTOMREQUEST, "PUT");
        }
        elseif ($type == 'DELETE')
        {
            curl_setopt($curl_request, CURLOPT_CUSTOMREQUEST, "DELETE");
        }
    
        curl_setopt($curl_request, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
        curl_setopt($curl_request, CURLOPT_HEADER, $returnHeaders);
        curl_setopt($curl_request, CURLOPT_SSL_VERIFYHOST, 0);  // wichtig
        curl_setopt($curl_request, CURLOPT_SSL_VERIFYPEER, 0);  // wichtig
        curl_setopt($curl_request, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl_request, CURLOPT_FOLLOWLOCATION, 0);
    
        if (!empty($oauthtoken)) 
        {
    		if ($fileHeader) {
    			curl_setopt($curl_request, CURLOPT_HTTPHEADER, array(
    				"oauth-token: {$oauthtoken}"));
    		} else {
                curl_setopt($curl_request, CURLOPT_HTTPHEADER, array(
    				"oauth-token: {$oauthtoken}",
    				"Content-Type: application/json"));
    		}		
        }
        else
        {
            curl_setopt($curl_request, CURLOPT_HTTPHEADER, array(
    			"Content-Type: application/json"));
        }
    
        if (!empty($arguments) && $type !== 'GET')
        {
            if ($encodeData)
            {
                //encode the arguments as JSON
                $arguments = json_encode($arguments);
            }
            curl_setopt($curl_request, CURLOPT_POSTFIELDS, $arguments);
        }
    
        $result = curl_exec($curl_request);
    	
        if ($returnHeaders)
        {
            //set headers from response
            list($headers, $content) = explode("\r\n\r\n", $result ,2);
            foreach (explode("\r\n",$headers) as $header)
            {
                header($header);
            }
    
            //return the nonheader data
            return trim($content);
        }
    
        curl_close($curl_request);
    
        //decode the response from JSON
        $response = json_decode($result);
    
        return $response;
    }
    ?>
    <?php
    if ($member_found) {
    	echo "<h1>Welcome ".$first_name." ".$last_name."</h1>";
    }

    Harald Kuske
    Principal Solution Architect – Professional Services, EMEA
    hkuske@sugarcrm.com
    SugarCRM Deutschland GmbH

  • Hi Harald,

    Creating the needed API as mentioned is that something standard (on the Sugar shelf) or is it totally tailored. I don't want to invent the wheel again if it's already be done in the past. We have a Sugar partner we use would they be able to make this happen or is it something you do?

    Rick  

  • Hi Rick,

    this can be done by any SugarCRM developer (e.g. partners). The description how REST endpoints are created can be found in the documentation https://support.sugarcrm.com/Documentation/Sugar_Developer/Sugar_Developer_Guide_10.2/Integration/Web_Services/REST_API/Extending_Endpoints/ 

    With such a custom endpoint an installation package for the module loader can be easily built https://support.sugarcrm.com/Documentation/Sugar_Developer/Sugar_Developer_Guide_10.2/Architecture/Module_Loader/ and installed.

    Harald Kuske
    Principal Solution Architect – Professional Services, EMEA
    hkuske@sugarcrm.com
    SugarCRM Deutschland GmbH