Dirk Harriman Banner Image

 

XML Nonce Register / Login


<?xml version="1.0" encoding="UTF-8"?> <users> <user user_id="0" status="1" access="2"> <user_name>jackJack23</user_name> <user_pass><![CDATA[$2y$10$qSnm/ii1nRgLMICFP2ta0ueb5SWPUhgboB.59nMjgI472BubweEIi]]></user_pass> </user> </users>

Top

<style type="text/css"> .flex_wrap {display:flex;flex-flow:row wrap;} .sel_control {margin:1rem;border:1px solid #000;border-radius:0.25rem;padding:0.25rem;} .btn_control {margin:1rem;border:1px solid #000;border-radius:0.25rem;padding:0.25rem 0.5rem;background-color:#000;color:#fff;} #user_message {margin:1rem;border:1px solid #000;border-radius:0.25rem;padding:0.25rem 0.5rem;min-height:10rem;} </style>

Top

<?php require_once('nonce.php'); $nonce = new Nonce(); $token = $nonce->generateNonce(10, 'form_login', 1); ?> ... <form id="form_login" name="form_login"> <input type="hidden" id="nonce_token" name="nonce_token" value="<?php echo $token; ?>" /> <div class="flex_wrap"> <input type="text" id="txtUsername" name="txtUsername" class="sel_control" minlength="8" maxlength="20" placeholder="Username" /> <input type="password" id="txtPassword" name="txtPassword" class="sel_control" minlength="8" maxlength="20" placeholder="Password" /> <input type="button" id="btnRegister" value="Register" class="btn_control" />  <input type="button" id="btnLogin" value="Login" class="btn_control" /><br/> </div> <div id="user_message"></div> </form>

Top

<script> window.addEventListener("DOMContentLoaded", (event) =>{ let txtUsername = document.getElementById("txtUsername"); let txtPassword = document.getElementById("txtPassword"); let btnLogin = document.getElementById("btnLogin"); let btnRegister = document.getElementById("btnRegister"); let user_message = document.getElementById("user_message"); let nonce_token = document.getElementById("nonce_token"); btnRegister.addEventListener("click", function() { let error_str = validate_login(); let data = ""; let msg = ""; let accessLevel = -1; let xmlhttp; let return_obj; if (error_str == "") { // PACKAGE THE DATA data = "txtUsername="+ txtUsername.value +"&txtPassword="+ txtPassword.value + "&nonce_token="+ nonce_token.value; if (window.XMLHttpRequest) { xmlhttp = new XMLHttpRequest(); } else { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.onreadystatechange=function() { if (xmlhttp.readyState==4 && xmlhttp.status==200) { /* 'errorString' => $error_str, 'userName' => $txtUsername, 'infoStr' => $info_str, 'userId' => $largest_id, 'accessLevel' => 2); */ returnObj = JSON.parse(xmlhttp.responseText); if (returnObj.errorString != "") { msg = "Error: "+ returnObj.errorString; } else { msg += returnObj.userName +"<br/>ID: "+ returnObj.userId +"<br/>"+ returnObj.infoStr +"<br/>"; accessLevel = parseInt(returnObj.accessLevel); switch (accessLevel) { case 0: msg += "Registered as Adminitrator"; break; case 1: msg += "Registered as Manager"; break; case 2: msg += "Registered as User"; break; default: msg += "not registered"; } } user_message.innerHTML = msg; } } xmlhttp.open("POST","notes_php6_back1.php",true); xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); xmlhttp.send(data); } else { user_message.innerHTML = error_str } },false); btnLogin.addEventListener("click", function() { let error_str = validate_login(); let data = ""; let msg = ""; let accessLevel = -1; let xmlhttp; let return_obj; if (error_str == "") { // PACKAGE THE DATA data = "txtUsername="+ txtUsername.value +"&txtPassword="+ txtPassword.value + "&nonce_token="+ nonce_token.value; if (window.XMLHttpRequest) { xmlhttp = new XMLHttpRequest(); } else { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.onreadystatechange=function() { if (xmlhttp.readyState==4 && xmlhttp.status==200) { returnObj = JSON.parse(xmlhttp.responseText); if (returnObj.errorString != "") { msg = "Error: "+ returnObj.errorString; } else { msg += returnObj.userName +"<br/>User ID: "+ returnObj.userId +"<br/>"+ returnObj.infoStr +"<br/>"; accessLevel = parseInt(returnObj.accessLevel); switch (accessLevel) { case 0: msg += "Logged in as Adminitrator"; break; case 1: msg += "Logged in as Manager"; break; case 2: msg += "Logged in as User"; break; default: msg += "Not logged in"; } msg += "<br/>"+ returnObj.userMenu; } user_message.innerHTML = msg; } } xmlhttp.open("POST","notes_php6_back2.php",true); xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); xmlhttp.send(data); } else { user_message.innerHTML = error_str; } },false); let validate_login = function() { let error_str = ""; if (txtUsername.value.trim() == "") { error_str += "You must enter a username<br/>"; } else { if (txtUsername.value.length < 8) { error_str += "Your username must be at least 8 characters long<br/>"; } } if (txtPassword.value.trim() == "") { error_str += "You must enter a password<br/>"; } else { if (txtPassword.value.length < 8) { error_str += "Your password must be at least 8 characters long<br/>"; } } return error_str; }; }); </script>

Top

The following code is code modified from code created by Simon Ugorji

<?php // NONCE LIBRARY session_start(); define('NONCE_SECRET', 'LaD^gEPr7#0oT$!s%KqHkM$^'); class Nonce { /************************************************************************************************ * GENERATE SALT */ private function generateSalt($length = 10){ // SET UP RANDOM CHARACTERS $chars='1uiop2rty34e5678fTYUIOPA90qwSDFGHcvbWEjkRJKLasdZXnmQghlzxCVBNM'; $char_len = strlen($chars)-1; // GET THE LENGTH OF THE RANDOM CHARACTERS $output = ''; while (strlen($output) < $length) { // GET RANDOM CHARACTERS AND APPEND TO OUTPUT UNTIL OUTPUT > $length $output .= $chars[ rand(0, $char_len) ]; } return $output; } /************************************************************************************************ * STORE NONCE */ private function storeNonce($form_id, $nonce){ // ARGUMENT MUST BE A STRING if (is_string($form_id) == false) { throw new InvalidArgumentException("A valid Form ID is required"); } // GROUP GENERATED NONCES AND STORE WITH md5 HASH $_SESSION['nonce'][$form_id] = md5($nonce); return true; } /************************************************************************************************ * GENERATE NONCE */ public function generateNonce($length = 10, $form_id, $expiry_time){ $secret = NONCE_SECRET; // SECRET MUST BE VALID. YOU CAN ADD YOUR regExp HERE if (is_string($secret) == false || strlen($secret) < 10) { throw new InvalidArgumentException("A valid Nonce Secret is required"); } $salt = self::generateSalt($length); // GENERATE SALT $time = time() + (60 * intval($expiry_time)); // CONVERT TIME TO SECONDS $toHash = $secret.$salt.$time; // CONCATENATE TOKENS TO HASH // SEND THIS TO THE USER WITH THE HASHED TOKENS $nonce = $salt .':'.$form_id.':'.$time.':'.hash('sha256', $toHash); self::storeNonce($form_id, $nonce); // STORE NONCE return $nonce; // RETURN NONCE } /************************************************************************************************ * VERIFY NONCE */ public function verifyNonce($nonce){ $secret = NONCE_SECRET; $split = explode(':', $nonce); // SPLIT NONCE WITH COLON DELIMETER if (count($split) !== 4) { // CHECK IF THE COUNT EQUALS 4 return false; } $salt = $split[0]; // SEPARATE SALT $form_id = $split[1]; // SEPARATE FORM ID $time = intval($split[2]); // SEPARATE TIME $oldHash = $split[3]; // SEPARATE OLD HASH if (time() > $time) { // CHECK IF THE TIME HAS EXPIRED return false; } if (isset($_SESSION['nonce'][$form_id])) { // CHECK IF NONCE IS PRESENT IN THE SESSION if ($_SESSION['nonce'][$form_id] !== md5($nonce)) { // CHECK IF HASHED VALUE MATCHES return false; } } else { return false; } // CHECK THE NONCE AGAINST $oldHash $toHash = $secret.$salt.$time; $reHashed = hash('sha256', $toHash); // MATCH WITH THE TOKEN if ($reHashed !== $oldHash) { return false; } return true; // NONCE IS VALID } } ?>

Top

<?php require_once('nonce.php'); // GET THE POSTED DATA - reg_add.php $txtUsername = $_POST['txtUsername']; $txtPassword = $_POST['txtPassword']; $nonce_token = $_POST['nonce_token']; $error_str = ''; $info_str = ''; $nonce = new Nonce(); if ($nonce->verifyNonce($nonce_token)) { $xml_file = 'site_users_nd1.xml'; $counter = 0; $info_str = 'Nonce Passed. '; /* * users * user user_id status access * user_name * user_pass */ if (file_exists($xml_file)) { $info_str .= 'File exists. '; $current_id = -1; $new_id = 0; $domDoc = new DOMDocument(); // CREATE A DOM DOCUMENT TO LOAD XML FILE DATA INTO $domDoc->preserveWhiteSpace = false; // SET PRESERVE WHITESPACE TO FALSE $domDoc->formatOutput = true; // MAKE OUTPUT FORMATTED WITH INDENTED CODE $domDoc->load($xml_file); // LOAD THE FILE DATA INTO THE DOM DOCUMENT $xpath = new DOMXPath($domDoc); // CREATE A NEW DOMXPath OBJECT FROM THE XML DOCUMENT $theDoc = $domDoc->documentElement; /* LOOP THROUGH ALL OF THE user NODES */ foreach($domDoc->getElementsByTagName('user') as $user) { $current_id = $user->getAttribute('user_id'); if ($current_id > $new_id) { $new_id = $current_id; } if ($user->getElementsByTagName('user_name')->item(0)->nodeValue == $txtUsername) { $error_str = 'Error: Username Already Exists'; } } if ($error_str == "") { $new_id++; $user = $domDoc->createElement('user'); $user->setAttribute( 'user_id', $new_id ); $user->setAttribute( 'status', '1' ); // ACTIVE $user->setAttribute( 'access', '2' ); // BASIC NON USER - TO BE MANUALLY EDITED $user_name = $domDoc->createElement('user_name', $txtUsername); $user_pass = $domDoc->createElement('user_pass'); // USER_PASS $user_pass->appendChild($domDoc->createCDataSection(password_hash($txtPassword, PASSWORD_DEFAULT))); // APPEND USER_NAME TO USER $user->appendChild( $user_name ); // APPEND USER_PASS TO USER $user->appendChild( $user_pass ); // APPEND USER TO USERS $theDoc->appendChild( $user ); // SAVE IN FILE "xml_users.xml" $domDoc->save($xml_file); $info_str .= 'User: '. $txtUsername .' registered. '; } } else { $info_str .= 'File does not exist. '; $new_id = 0; /* FILE DOES NOT EXIST, SO CREATE XML TO BE SAVED TO FILE */ $domDoc = new DomDocument('1.0', 'UTF-8'); $domDoc->preserveWhiteSpace = false; $domDoc->formatOutput = true; // ADD ROOT ELEMENT $users = $domDoc->appendChild($domDoc->createElement('users')); // CREATE USER NODE $user = $domDoc->createElement('user'); $user->setAttribute( 'user_id', '0' ); // FIRST USER $user->setAttribute( 'status', '1' ); // ACTIVE $user->setAttribute( 'access', '2' ); // BASIC NON USER - TO BE MANUALLY EDITED $user_name = $domDoc->createElement('user_name', $txtUsername); $user_pass = $domDoc->createElement('user_pass'); // USER_PASS $user_pass->appendChild($domDoc->createCDataSection(password_hash($txtPassword, PASSWORD_DEFAULT))); // APPEND USER_NAME TO USER $user->appendChild( $user_name ); // APPEND USER_PASS TO USER $user->appendChild( $user_pass ); // APPEND USER TO USERS $users->appendChild( $user ); // SAVE IN FILE "xml_users.xml" $domDoc->save($xml_file); $info_str .= 'New file created. User: '. $txtUsername .' registered. '; } } else { $error_str = 'Nonce Failed'; } $output = array('errorString' => $error_str, 'infoStr' => $info_str, 'userName' => $txtUsername, 'userId' => $new_id, 'accessLevel' => 2); header('Content-Type:application/json'); echo json_encode($output, JSON_FORCE_OBJECT); ?>

Top

<?php require_once('nonce.php'); $txtUsername = $_POST['txtUsername']; $txtPassword = $_POST['txtPassword']; $nonce_token = $_POST['nonce_token']; $error_str = ''; $info_str = ''; $nonce = new Nonce(); if ($nonce->verifyNonce($nonce_token)) { $xml_file = 'site_users_nd1.xml'; $counter = 0; $info_str = 'Nonce Passed. '; $menu_str = ''; $access_level = -1; $user_id = -1; /* * users * user user_id status access * user_name * user_pass */ if (file_exists($xml_file)) { $domDoc = new DOMDocument(); // CREATE A DOM DOCUMENT TO LOAD XML FILE DATA INTO $domDoc->preserveWhiteSpace = false; // SET PRESERVE WHITESPACE TO FALSE $domDoc->formatOutput = true; // MAKE OUTPUT FORMATTED WITH INDENTED CODE $domDoc->load($xml_file); // LOAD THE FILE DATA INTO THE DOM DOCUMENT foreach($domDoc->getElementsByTagName('user') as $user) { if ($user->getElementsByTagName('user_name')->item(0)->nodeValue == $txtUsername) { if (password_verify($txtPassword, $user->getElementsByTagName('user_pass')->item(0)->nodeValue)) { // START A SESSION //session_start(); $access_level = (int)$user->getAttribute('access'); $user_id = (int)$user->getAttribute('user_id'); $_SESSION['access'] = $access_level; $_SESSION['sid'] = $user_id; $_SESSION['user_name'] = $txtUsername; switch($access_level) { case 0 : $menu_str = '<a href="#" class="btn btn-bs-primary">Admin Page</a>'; break; case 1 : $menu_str = '<a href="#" class="btn btn-bs-primary">Manager Page</a>'; break; case 2 : $menu_str = '<a href="#" class="btn btn-bs-primary">User Page</a>'; break; default: $menu_str = ''; } } } } if ($access_level == -1) { $error_str = 'Login Failed'; } } else { $error_str = 'File Does Not Exist'; } } else { $error_str = 'Nonce Failed'; } $output = array('errorString' => $error_str, 'userName' => $txtUsername, 'infoStr' => $info_str, 'userId' => $user_id, 'userMenu' => $menu_str, 'accessLevel' => $access_level); header('Content-Type:application/json'); echo json_encode($output, JSON_FORCE_OBJECT); ?>

Top