What is 3D Issue Custom User Login
3D Issue Custom User Login allows our clients to implement a secure login on their Flipbooks but instead of storing the end readers credentials on the 3D Issue servers, the client can use their own set of user credentials
Why is this important?
This is important as some clients may have a large set of employees or existing members / readers. Instead of having to re-enter all these user details onto the 3D Issue servers, the client can create a webservice on their end and interact with their own database / store of user credentials. That way, if the users details change on the customers system, the details will automatically be reflected for the end user when they read a 3D Issue Flipbook.
How does it work
This service works in that the customer will need to implement a rest endpoint on their system to handle logins. Instead of checking credentials on the 3D Issue server, we will call the customers web service and it is up to the customer’s code to verify if the user is allowed to view the Flipbook in question or not. The endpoint will then return a JSON response in the format specified by 3D Issue
What the customer needs to do to enable Custom User Login
The customer will need to develop a custom rest web service that corresponds to requirements as laid out by 3D Issue. This web service can be written in any language and code samples can be found in this document.
Endpoint Parameters
The web service will need to accept 4 parameters;
- userName
- password
- publicationURL
- issueName
The userName and password are the credentials that will be entered by the user when prompted from the user login.
An example of a request to this web service would look something like;
https://api.mydomain.com/login?userName=jeff&password=supersecrectpassword123&publicationURL=https://cloud.3dissue.com/1/1/1/sample1/index.html&issueName=sample1
Expected Responses
Valid Login
If the login is valid – the rest call should return the response;
{"loginValid":"true"}
Invalid Login
If the login is invalid – the rest call should return the response;
{"loginValid":"false"}
After creating the web service
After the customer develops the web service – they must provide the 3D Issue team with the following
- URL of the web service endpoint (e.g.http://3dissue.com/rest/userLogin)
- A valid userName and password so we can test your service.
- A link to a Flipbook that has been created with Login Enabled.
3D Issue will then test and enable the custom login endpoint.
Sample Code
PHP
In this sample code, a userName of valid and a password of valid will return a success response. Any other username and password combination will return a failure response
<?php /* This script provides a RESTful API interface for a web application Input: $_GET['format'] = [ json | html | xml ] $_GET['method'] = [] Output: A formatted HTTP response */ /** * Deliver HTTP Response * @param string $format The desired HTTP response content type: [json, html, xml] * @param string $api_response The desired HTTP response data * @return void **/ function deliver_response($format, $api_response){ // Define HTTP responses $http_response_code = array( 200 => 'OK', 400 => 'Bad Request', 401 => 'Unauthorized', 403 => 'Forbidden', 404 => 'Not Found' ); // Set HTTP Response header('HTTP/1.1 '.$api_response['status'].' '.$http_response_code[ $api_response['status'] ]); // Process different content types //if( strcasecmp($format,'json') == 0 ){ // Set HTTP Response Content Type header('Content-Type: application/json; charset=utf-8'); // Format data into a JSON response $json_response = json_encode($api_response); // Deliver formatted data echo $json_response; // End script process exit; } // Define whether an HTTPS connection is required $HTTPS_required = FALSE; // Define whether user authentication is required $authentication_required = FALSE; // Define API response codes and their related HTTP response $api_response_code = array( 0 => array('HTTP Response' => 400, 'Message' => 'Unknown Error'), 1 => array('HTTP Response' => 200, 'Message' => 'Success'), 2 => array('HTTP Response' => 403, 'Message' => 'HTTPS Required'), 3 => array('HTTP Response' => 401, 'Message' => 'Authentication Required'), 4 => array('HTTP Response' => 401, 'Message' => 'Authentication Failed'), 5 => array('HTTP Response' => 404, 'Message' => 'Invalid Request'), 6 => array('HTTP Response' => 400, 'Message' => 'Invalid Response Format') ); // Set default HTTP response of 'ok' $response['code'] = 0; $response['status'] = 404; $response['data'] = NULL; //Need to get the hashCode of the users password as 3DIssue passes in the hashed version of the password entered by the user //this is to ensure some level of security between the user entering their details in the userLogin form and the transport to our servers if( strcasecmp($_GET['userName'],'valid') == 0 && strcasecmp($_GET['password'],'valid' ) == 0){ $response['code'] = 1; $response['status'] = $api_response_code[ $response['code'] ]['HTTP Response']; $response['loginValid'] = 'true'; } else { $response['code'] = 1; $response['status'] = $api_response_code[ $response['code'] ]['HTTP Response']; $response['loginValid'] = 'false'; } $response['userName'] = $_GET['userName']; $response['password'] = $_GET['password']; $response['publicationURL'] = $_GET['publicationURL']; $response['issueName'] = $_GET['issueName']; // --- Step 4: Deliver Response // Return Response to browser deliver_response($_GET['format'], $response); ?>
Grails
In this sample code, a userName of valid and a password of valid will return a success response. Any other username and password combination will return a failure response
/** * Rest call for performing the dummy user login call */ @Secured('IS_AUTHENTICATED_ANONYMOUSLY') def dummyUserLoginWebserviceCall = { String callback = params.callback //Grab the userName from the userLoginService String userName = params.userName; String password = params.password; String publicationURL = params.publicationURL; String issueName = params.issueName; String validUsername = "valid"; String validPassword = "valid"; //String hashedValidPassword = validPassword.hashCode(); def builder = new JsonBuilder() if (userName.equals(validUsername) && password.equals(validPassword)) { def root = builder { loginValid "true" } } else { def root = builder { loginValid "false" } } def jsonResponse = builder.toString() //hack to get around bug with setting contentType from jquery, if the callback is set, we will set the callback on the returned json response if (callback) { log.info "[processDummyUserLogin]Callback is " + callback //String callback = params['callback']; jsonResponse = callback + '(' + jsonResponse + ');' } render jsonResponse; }