Layar Developer Documentation

Back to layar.com

Implement user authentication in a layer

Sometimes, you might want to reveal AR content in a layer based on different user group. For instance, only a logged in user can see certain type of content. In this tutorial, we will demonstrate how to implement user authentication mechanism in a layer. Before we get started, you are strongly recommended to read here to understand the general flow of user authentication. In this tutorial, AR content will be shown only when a user is logged in successfully. 

What we want to achieve is the following sequence:

The following steps need to be done:

Please NOTE that this tutorial (including the sample code) is ONLY to demonstrate how user authentication mechanism works in Layar. Developers should add more security checks and validation rules on user input data. For instance, always use HTTPS rather than the standard HTTP.

Enable user authentication on the publishing site 

To enable user authentication mechanism, we will configure the "Additional settings" page as follows:

user authentication - additional settings page

The detailed explanation on each field can be found on Howto - User Authentication page. 

Create a User table in the database

We will create a User table to store user account information, namely username and password. The following sql query is used to create the User table and the "username" should be unique.

CREATE TABLE IF NOT EXISTS `User` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(20) NOT NULL,
  `password` varchar(64) NOT NULL,
  `salt` varchar(15) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `username` (`username`)
) ;

We also add a "salt" with a length of 15 chars. It is used to lengthen the password and also creates random hash code for each password. The objective is to better encrypt user password.

We also create two pages adduser.php and adduser_submit.php for users to create an account in User table. These files have been provided in the sample code at the end of the tutorial.

Logging in 

On the publishing site, we have provided a link in "URL for layer settings page". In this loginForm.php script, we will check whether a user is already logged in. If we can not detect a valid session cookie, a login form is shown so that user can fill in their user name and password to login. Otherwise, a loggedin.php page is shown where user can choose to logout or go to the AR view directly without logging in again.

Now lets have a look at loginForm.php.

<?php
// allow sessions to be passed so we can see if the user is logged in
session_start();
// include database connection details
require_once('config.inc.php');
// Include the custom functions.
include "functions.php";
// define an empty string $message
$message = "";

/*** Check if the user is already logged in ***/
if (isLoggedIn()) {
  // if there is, it logs you in and directes you to the loggedin page
  header( "location:loggedin.php" ); 
  // Make sure that code below does not get executed when we redirect.
  exit;
} // if

/*** Check that both the username, password have been submitted ***/
// if form has been submitted
if ( isset($_POST['submit']) ) {
  // protect the posted value
  $phpro_username = protect($_POST['username']);
  $phpro_password = protect($_POST['pass']);
  // makes sure they filled in both username and password.
  if( !isset($phpro_username, $phpro_password) ) {
    $message = "You did not fill in a required field.";
  } // if

  /*** if we are here the data is filled in and we can check whether the user exists in the database ***/
  // connect to database
  try {
    $db = connectDb();
    if ($db) {
        // prepare the select statement
      $stmt = $db->prepare(" SELECT id, password, salt
                               FROM User
                              WHERE username = :phpro_username
                              limit 1 ");
      // bind the parameters
      $stmt->bindParam(':phpro_username', $phpro_username, PDO::PARAM_STR);       
      // execute the prepared statement
      $stmt->execute();       
      //check for a result
      $user = $stmt->fetch(PDO::FETCH_ASSOC);

      /*** if we have no result then reply that the login failed ***/
      if( $user == false ) {
        $message = "No record. Login Failed. Please try it again.";
      } //if
      else {
        $salt = $user['salt'];
        $password = $user['password'];
        // hash the password and enhance it with salt
        $hashed_password = hashPass($phpro_password, $salt);
       
        /*** if the passwords are matched, we set the session variables ***/
        if( $hashed_password == $password ) {  
           // regenerate a new session id to prevent session fixation.
           session_regenerate_id(true);
           // set up the session variables. $_SESSION['valid'] determines
           // whether a user is logged in or not.      
           $_SESSION['valid'] = 1;
           session_write_close();
           // redirect the user to the Camera view once the cookie is set.
           // NOTE: please use the right layer name.
           header("Location:layar://layername/?action=refresh");
           // Make sure that code below does not get executed when we redirect.
             exit;
        }// if  
        else
          $message ="login failed. please try it again.";
      } // else
    } // if  
  }//try
  catch(Exception $e) {
    /*** if we are here, something has gone wrong with the database ***/
    $message = "We are unable to process your request. Please try again later";
  }//catch
}//if

?>
<html>
<head>
<title>LOGIN</title>
</head>
<body>
<form action="<?php echo $_SERVER['PHP_SELF']?>" method="post">
<table border="0">
<tr><td colspan=2><h1>Login</h1></td></tr>
<tr><td>Username:</td><td>
<input type="text" name="username" maxlength="20">
</td></tr>
<tr><td>Password:</td><td>
<input type="password" name="pass">
</td></tr>
<tr><td colspan="2" align="right">
<input type="submit" name="submit" value="Login">
</td></tr>
</table>
</form>
<b>If you haven't signed up. <a href=adduser.php>Click Here to Register</a></b>
<p>
<?php

// If there is any error message, show it here.
if ($message != "")    
    echo "error message:". $message ;
?>
</body>
</html>

As you can see in the script above, we firstly use function isLoggedIn() to check whether $_SESSION['valid'] is set and valid. This function is defined in functions.php. If a user is already logged in, the user is directed to a page called loggedin.php. If a user is not logged in, a login form is shown. After filling in the correct username and password, $_SESSION['valid'] is set and the user is directed to the Camera view using a layar intent (header("Location:layar://layername/?action=refresh");). Please make sure that you specify this link when you try out the sample code.

Return POIs when user is logged 

In POI provider service, if a user is already logged in ($_SESSION['valid'] is set and valid), we will search through the POI table to return POIs within the search range. If user is not logged in, an errorCode 30 will be returned in the getPOIs response. The Layar client will open the page defined for "URL for layer settings page" (in our case, loginForm.php) when errorCode 30 is returned.

The implementation looks like:

// Start the session
session_start();

... // defined custom functions.

/*** Main entry point ***/

/* Put parameters from GetPOI request into an associative array named $requestParams */
// Put needed parameter names from GetPOI request in an array called $keys.
$keys = array( 'layerName', 'lat', 'lon', 'radius' );
// Initialize an empty associative array.
$requestParams = array();
// Call funtion getRequestParams()  
$requestParams = getRequestParams($keys);

/* Connect to MySQL server. We use PDO which is a PHP extension to formalise database connection.
     For more information regarding PDO, please see http://php.net/manual/en/book.pdo.php.
 */    
// Connect to predefined MySQl database.  
$db = connectDb();
    
/* Construct the response into an associative array.*/
// Create an empty array named response.
$response = array();
// Assign cooresponding values to mandatory JSON response keys.
$response['layer'] = $requestParams['layerName'];
   
/* If no session cookie is present, return empty hotspots array and errorCode 30. */
if (!isLoggedIn()) {
  $response['hotspots'] = array();    
  $response["errorCode"] = 30;
  $response["errorString"] = "Please login to see AR content .";
} //if the user is not logged in

/* If user is logged in, retrieve POIs within search range. */
else {
  // Use getHotspots() function to retrieve POIs with in the search range.  
  $response["hotspots"] = getHotspots($db, $requestParams);
  // if there is no POI found, return a custom error message.
  if (empty($response["hotspots"])) {
    $response["errorCode"] = 20;
    $response["errorString"] = "No POI found. Please adjust the range.";
  }//if
  else {
    $response["errorCode"] = 0;
    $response["errorString"] = "ok";
  }//else
}// else there is a session

/* All data is in $response, print it into JSON format.*/

// Put the JSON representation of $response into $jsonresponse.
$jsonresponse = json_encode( $response );   
// Declare the correct content type in HTTP response header.
header( "Content-type: application/json; charset=utf-8" );   
// Print out Json response.
echo $jsonresponse;

Please NOTE that we did not list all the custom functions here due to the size of the tutorial. They are defined in functions.php.

To summarize, we have created the following pages to enable user authentication mechanism in Layar:

You can download the attached Sample Code to play with it. Please make sure that you read the readmefirst.txt first.