Jump to content
Larry Ullman's Book Forums

Jonathon

Members
  • Posts

    1064
  • Joined

  • Last visited

  • Days Won

    55

Everything posted by Jonathon

  1. are you using a php extension? ie "templates.php" - what does the page return and what does the view source code return?
  2. If this is a live server it is often a requirement that you set the timezone using the function listed above. I usually just put this in my config file and you should be fine. Just look up the function on php.net to see what is the best timezone to pass it for you.
  3. I don't have this book so I don't know what's covered in it, but you can use $_SESSION instead
  4. I don't know what you mean. What code are you running? Do you get an error?
  5. The code posted does match that in the Advanced book (As i'm sure you know)
  6. I noticed the tip in the book and also in practice across chrome, opera, ff, safari and ie. I think only chrome actually opened it in the browser the rest opened it up in whatever pdf reader I have and some asked me whether or not I wanted to save it. I think I'm just going to keep it as it is. Thanks for the reply though.
  7. Well the example shows PDFs through the browser, but I wanted to put an option in that also allowed for a straight download of the PDF using something like header ("Content-Type: application/pdf\n"); header ("Content-disposition: attachment; filename=\"$filename\"\n"); header ("Content-Length: $filesize\n"); readfile ($full_path_to_file . $filename); As I said I don't think its much of an issue really, more curiosity really.
  8. I was just wondering, does including a forced download link for PDFs in accompaniment to viewing the PDFs break the whole idea of serving PDFs through a proxy? I feel like it would. To be honest I'm not even sure that's necessary really, Most browsers seem to prompt you on whether you want to just open or save the PDF anyway. But I was curious, so thought I'd ask? Thanks Jonathon
  9. I don't think you need to use the subversion for it to work. On my site setup for ..... in the site tab i have the: Site name = 'what ever you want to call it' local site folder = 'C:\xampp\htdocs\' the servers tab i have: Server name = 'localhost' Connect using 'Local/Network' Server folder = 'C:\xampp\htdocs\' Web URL = 'http://localhost/' Make sure that the "Testing" box is highlighted also Version control = Access = None That's about it really, works for me, hope it helps
  10. I think the RIGHT and LEFT calls in MySQL return a string by character length. I don't really know the answer, maybe explode the string returned and return 1 less than the length of elements that way you wouldn't run the risk that the last element is only a partial word...?
  11. That's no problem, I obviously spent quite a lot time looking up prepared statements and data types for MYSQL and I never found anything at all. Maybe there's some little quirk in my XAMPP or something. But thanks for your help, good to get it sorted (I hope) as I like prepared statements
  12. I didn't realise you'd commented , you may be able to tell from my previous post that this is the route I am gearing towards. so if I change the function to function passwordHash($password) { // the database connection global $dbc; // return the escaped password return hash_hmac('sha256', $password, 'c#haRl891'); } // end of passwordHash() function Change the 's' flag as mentioned above. Change the database field of `pass` to a VARCHAR and what length would you advise (64)?? Is that the maximum it can return? I should be all good?
  13. I echoed out strlen($p) after I has $p and it returned 32 as the length, I then altered the varbinary field to (1000) in length and still the same result. To Update: The only way I seem to be able to insert data into the pword field is by setting the data-type to 's' not 'b'. I compared inserting a password like this against a standard query and the result is that the prepared statement hash of the exact same password is 2 characters shorter. To further update: I have used the prepared statement above (in the full code) but changed the 'blob' to a 'string' this allowed a password to be registered in the field. Which suggests to me that standard SQL inserts binary as a string. Because looking at the my old database for Larry's ecommerce 1 example the passwords are stored as 32 character long hexadecimal hashes. Now I'm not sure whether that means that the prepared statements insertion should be stored this way, but I don't really understand why the standard vs the prepared way should differ in how they are stored?? But what I did then was this short basic code, which is documented so you can follow: // inserted password hash from registering, taken from DB $inserted = 'd1ca230e50b724f50c9eb8e2e8bf17e0431dd51c6f277c784ea081d513d927ab'; echo $inserted; echo '<br />'; // hardcode the password $p = 'passworD5'; // run the password through the hash $p = passwordHash($p); // what length is returned echo 'The password is ' . strlen($p) . ' long'; echo '<br />'; // convert $p from binary to hex representational to compare visually echo bin2hex($p); // convert $p to be hex representation $p = bin2hex($p); echo '<br />'; // check if inserted value is implicitly equal to $p value that is generated in the script if($inserted === $p) { echo 'Yes - we are equal'; } else { echo 'No - we aren\'t equal'; } echo '<br />'; if((strcmp($inserted, $p) === 0)) { echo 'Case sensitive match'; } else { echo 'Case sensitive fail'; } Now that returned:
  14. Hi Antonio, Yeah I know 'b' is for blob, but the passwordHash I'm using returns binary data. It inserts a hex hash when I use a standard SQL query, which i suppose is a fail safe, but I want to use prepared statements. This is the password hash by the way, I think its posted earlier on too function passwordHash($password) { // the database connection global $dbc; // return the escaped password return hash_hmac('sha256', $password, 'c#haRl891', true); } // end of passwordHash() function
  15. This is the SQL structure for my table in case anyone wanted to know CREATE TABLE IF NOT EXISTS `users` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `type` varchar(6) NOT NULL DEFAULT 'member', `company` varchar(50) NOT NULL, `email` varchar(80) NOT NULL, `pass` varbinary(32) NOT NULL, `first_name` varchar(20) NOT NULL, `last_name` varchar(40) NOT NULL, `active` char(32) DEFAULT NULL, `date_created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `date_modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', PRIMARY KEY (`id`), UNIQUE KEY `email` (`email`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ; And the code for my registration script is: // validate registration // did you submit form if($_SERVER['REQUEST_METHOD'] == 'POST'){ // prepare databse to insert $query = "INSERT INTO `users` (`first_name`, `last_name`, `email`, `company`, `pass`, `active`) VALUES (?, ?, ?, ?, ?, ?)"; $stmt = mysqli_prepare($dbc, $query); mysqli_stmt_bind_param ($stmt, 'ssssbs', $fn, $ln, $e, $comp, $p, $active); // check for first name // allows letters, a space, full stop, apostrophe, hyphen if (preg_match ('/^[A-Z \'.-]{2,20}$/i', $_POST['first_name'])) { $fn = $_POST['first_name']; } else { $errors['first_name'] = 'Please enter your first name!'; } // check for last name if(preg_match('/^[A-Z\'.-]{2,40}$/i', $_POST['last_name'])) { $ln = $_POST['last_name']; } else { $errors['last_name'] = 'Please enter your last name'; } // check email address if(filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) { $e = $_POST['email']; } else { $errors['email'] = 'Please enter a valid email address'; } // check for company if(preg_match('/^[A-Z\'.-]{2,40}$/i', $_POST['company'])) { $comp = $_POST['company']; } else { $errors['company'] = 'Please enter your company name or state individual'; } // check for a password and match against the confirmed password: if (preg_match ('/^(\w*(?=\w*\d)(?=\w*[a-z])(?=\w*[A-Z])\w*){6,20}$/', $_POST['pass1']) ) { if ($_POST['pass1'] == $_POST['pass2']) { $p = passwordHash($_POST['pass1']); } else { $errors['pass2'] = 'Your password did not match the confirmed password!'; } } else { $errors['pass1'] = '6-20 characters long with at least 1 lower-case letter, 1 upper-case letters & 1 number'; } if(empty($errors)) { // prepare emal query if email is in DB $q = "SELECT `email` FROM `users` WHERE `email`='$e'"; $r = mysqli_query($dbc, $q); if (mysqli_num_rows($r) === 0) { // no user exists $active = md5(uniqid(rand(), true)); // create activation code mysqli_stmt_execute($stmt); if(mysqli_stmt_affected_rows($stmt) === 1) { echo '<div id="content"> <div class="register"> <h3>Thanks For Registering</h3><p>You have been succesfully registered please check your email account for an activation email.</p> </div></div>'; // call activation email script // pass name, email and firstname to script activationEmail($active, $fn, $e); //include footer include('include/footer.inc.php'); echo '</body></html>'; exit(); } else { // query failed trigger_error('<div id="content"><div class="register"><p class="error">You Could not be registered at this time due to a system error. We apologize for any inconvenience</p></div></div>'); } } else { // email in use $row = mysqli_fetch_array($r, MYSQLI_NUM); if($row[0] == $_POST['email']){ $errors['email'] = ' This email is already registered,<a href="' . BASE_URL . 'forgotten-password"> forgot password</a>'; } } // end of email registered already } // clode statement mysqli_stmt_close($stmt); // close connection mysqli_close($dbc); } // end of submitted form ?> //***THE FROM IS THIS TOO******// <form action="<?php echo BASE_URL; ?>register" method="post" accept-charset="utf-8"> <p><label>First Name:</label><input type="text" name="first_name" id="first_name" value="<?php if(isset($_POST['first_name'])) { echo $_POST['first_name']; } ?>" /> <span><?php if (isset($errors['first_name'])) { echo $errors['first_name']; } ?></span></p> <p><label>Last Name:</label><input type="text" name="last_name" id="last_name" value="<?php if(isset($_POST['last_name'])) { echo $_POST['last_name']; } ?>" /> <span><?php if (isset($errors['last_name'])) { echo $errors['last_name']; } ?></span></p> <p><label>Email:</label><input type="text" name="email" id="email" value="<?php if(isset($_POST['email'])) { echo $_POST['email']; } ?>"/> <span><?php if (isset($errors['email'])) { echo $errors['email']; } ?></span></p> <p><label>Company:</label><input type="text" name="company" id="company" value="<?php if(isset($_POST['company'])) { echo $_POST['company']; } ?>"/> <span><?php if (isset($errors['company'])) { echo $errors['company']; } ?></span></p> <p><label>Password:</label><input type="password" name="pass1" id="pass" /> <span><?php if(isset($errors['pass1'])) { echo $errors['pass1']; } ?></span></p> <p><label>Confirm Password:</label><input type="password" name="pass2" id="pass2" /> <span><?php if(isset($errors['pass2'])) { echo $errors['pass2']; } ?></span></p> <p><input type="submit" name="submit" value="Register" /></p> </form> I just looked at it again and still no password gets submitted. I echoed out the value of $p also just before the statement is executed and it had a value of "��+\"P-��@mk��7��� -(v^G=rM��" so at the point of execution it does have a value. I'm really stumped.
  16. Yeah sure, the query failed at a PHP level so I broke down the query within the client to isolate what field was producing the error.
  17. Hi Larry my password column is called `pass` and is defined as varbinary(32) NOT NULL. From what you've said I've changed the code so that I don't run the value of the password form input through the mysqli_real_escape_string. if (preg_match ('/^(\w*(?=\w*\d)(?=\w*[a-z])(?=\w*[A-Z])\w*){6,20}$/', $_POST['pass1']) ) { if ($_POST['pass1'] == $_POST['pass2']) { $p = $_POST['pass1']; } else { $errors['pass2'] = 'Your password did not match the confirmed password!'; } } else { $errors['pass1'] = '6-20 characters long with at least 1 lower-case letter, 1 upper-case letters & 1 number'; } I shall also remove / alter the rest of my registration form validation so that I don't run the $_POST variables through the mysqli_real_escape_string. I also take it I should alter my password function so that it looks like: function passwordHash($password) { // the database connection global $dbc; // return the escaped password return hash_hmac('sha256', $password, 'c#haRl891', true); } // end of passwordHash() function Is that what you wanted me to do? I still then hashed the $_POST['pass1'] before executing the query though. As i thought that it was the right thing to do, but the password field was still blank upon registering
  18. Hi Larry, thanks for your input, i do appreciate it, I changed my query to // prepare databse $query = "INSERT INTO `users` (`first_name`, `last_name`, `email`, `company`, `pass`, `active`) VALUES (?, ?, ?, ?, ?, ?)"; $stmt = mysqli_prepare($dbc, $query); mysqli_stmt_bind_param ($stmt, 'ssssbs', $fn, $ln, $e, $comp, $p, $active); Retrieved the password as normal using // check for a password and match against the confirmed password: if (preg_match ('/^(\w*(?=\w*\d)(?=\w*[a-z])(?=\w*[A-Z])\w*){6,20}$/', $_POST['pass1']) ) { if ($_POST['pass1'] == $_POST['pass2']) { $p = mysqli_real_escape_string($dbc, $_POST['pass1']); } else { $errors['pass2'] = 'Your password did not match the confirmed password!'; } } else { $errors['pass1'] = '6-20 characters long with at least 1 lower-case letter, 1 upper-case letters & 1 number'; } And then executed the query like so: if(empty($errors)) { $q = "SELECT `email` FROM `users` WHERE `email`='$e'"; $r = mysqli_query($dbc, $q); $rows = mysqli_num_rows($r); if($rows === 0){ // No users exist $active = md5(uniqid(rand(), true)); $p = passwordHash($p); // execute query mysqli_stmt_execute($stmt); if(mysqli_stmt_affected_rows($stmt) == 1) { // rest of code It says i've registered but on inspection of the DB the password column is empty. I tried doing this earlier and it was empty then so I just assumed and still do that this wrong. I echoed the variables out at each stage too, after I first got $p and ran it through mysqli_real_escape_Sting and its value was as expected and then i echoed out $p after the hash and it returned some weird characters which i believe to be a binary representation ��+\"P-��@mk��7��� -(v^G=rM��
  19. Hi Larry, Thanks, i see, I did wonder about that. My passwordHash() is basically the same as your function function get_password_hash($password) { // Need the database connection: global $dbc; // Return the escaped password: return mysqli_real_escape_string ($dbc, hash_hmac('sha256', $password, 'c#haRl891', true)); } in the ecommerce example but I have a different 'key' within the hash where yours is 'c#haRl891'. I tried: $query = "INSERT INTO `users` (`first_name`, `last_name`, `email`, `company`, `pass`, `active`) VALUES (?, ?, ?, ?,passwordHash(?), ?)"; $stmt = mysqli_prepare($dbc, $query); mysqli_stmt_bind_param ($stmt, 'ssssbs', $fn, $ln, $e, $comp, $p, $active); // altered the 's' to 'b' for binary which returns an error saying the number of variables doesn't match, so I tried to concatenate it like (?, ?, ?, ?,' . passwordHash(?) . ', ?)"; and it throws an "Number of variables doesn't match number of parameters in prepared statement error" So i guess my question is how do you write a prepared statement query to accept a function call within a query. I did Google it and someone somewhere basically hashed the string before it got inserted into the DB. Which i suppose works, but it is the source of my errors.
×
×
  • Create New...