Ohh, got it. But i'm not sure about how to use verifyCookie($token). Could you show me an example?
Another thing, what exists() does?
Check my Code
Moderator: General Moderators
Re: Check my Code
exists() checks whether the user exists in the database. Well, technically, that's what validate() does, but validate() is a private function.
I must have been half asleep when I wrote verifyCookie(). The idea is to check for the existence of a 'token' cookie, pass it to the verifyCookie() function, and get back the userID or FALSE if no match is found. Trouble is, you'd need to instantiate the User object, which you can't do without a username. Like I said, I must have been half asleep. It needs rewriting. And rethinking.
I must have been half asleep when I wrote verifyCookie(). The idea is to check for the existence of a 'token' cookie, pass it to the verifyCookie() function, and get back the userID or FALSE if no match is found. Trouble is, you'd need to instantiate the User object, which you can't do without a username. Like I said, I must have been half asleep. It needs rewriting. And rethinking.
-
ibnclaudius
- Forum Newbie
- Posts: 12
- Joined: Thu Dec 08, 2011 7:41 pm
Re: Check my Code
I am not sure why have three functions doing basically the same thing: login(), validate(), exists()
About the problem with the cookie, you have an idea about how to fix it?
This is what I have:
login.php
class.php
db.sql
I'm not sure about how hashPassword() works. Each user will have a different $salt and it will be the created date?
About the problem with the cookie, you have an idea about how to fix it?
This is what I have:
login.php
Code: Select all
<?php
session_start();
include 'class.php';
if (isset($_POST['username']) && isset($_POST['password'])) {
$user = new User($_POST['username']);
if ($user->exists()) {
$login = $user->login($_POST['password']);
if ($login) {
$_SESSION['user_id'] = $login;
session_write_close();
} else {
echo "Login failed.";
}
} else {
header("Location: register.php");
}
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Login Form</title>
</head>
<body>
<form action="" method="post">
<label for="username">Username: </label>
<input type="text" name="username" /><br />
<label for="password">Password: </label>
<input type="password" name="password" /><br />
<input type="submit" value="Submit" />
</form>
</body>
</html>Code: Select all
<?php
class User {
protected $id;
protected $username;
protected $email;
protected $sql;
private $exists = FALSE;
public function __construct($username) {
if (empty($username)) {
throw new Exception('Username cannot be blank.');
}
$this->username = $username;
$this->sql = new PDO(DSN, DBUSER, DBPASS);
$this->exists = $this->validate();
}
private function createLoginToken($id) {
$token = $id . md5(microtime());
$expires = new DateTime();
$expires->add(new DateInterval('P30D'));
$query = "INSERT INTO sessions (userID, token, expires)
VALUES (:id, :token, :expires)";
$stmt = $this->sql->prepare($query);
$stmt->execute(array(':id' => $id,
':token' => $token,
':expires' => $expires->format('Y-m-d H:i:s')));
setcookie('token', $token, $expires->getTimestamp(), '/');
}
private function hashPassword($password, $salt) {
$string = PASSWORD_SALT . $password . md5($salt);
$hashed = crypt($string, '$2a$12$' . substr(md5($salt), 0, 22));
return $hashed;
}
private function validate() {
$query = "SELECT COUNT(id)
FROM users
WHERE username = :username";
$stmt = $this->sql->prepare($query);
$stmt->execute(array(':username' => $this->username));
$count = $stmt->fetchColumn();
return ($count > 0) ? TRUE : FALSE;
}
public function exists() {
return $this->exists;
}
public function login($password, $remember = FALSE) {
$query = "SELECT id, password, UNIX_TIMESTAMP(created) AS salt
FROM users
WHERE username = :username";
$stmt = $this->sql->prepare($query);
$stmt->execute(array(':username' => $this->username));
$row = $stmt->fetch(PDO::FETCH_OBJ);
$hashed = $this->hashPassword($password, $row->salt);
if ($row->password == $hashed) {
if ($remember) {
$this->createLoginToken($row->id);
}
return $row->id;
}
return FALSE;
}
public function registerUser($password, $email) {
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new Exception('Email does not appear to be valid.');
}
$this->email = $email;
$date = new DateTime();
$hashed = $this->hashPassword($password, $date->getTimestamp());
$query = "INSERT INTO users (username, password, email, created)
VALUES (:username, :password, :email, :created)";
$stmt = $this->sql->prepare($query);
$success = $stmt->execute(array(':username' => $this->username,
':password' => $hashed,
':email' => $email,
':created' => $date->format('Y-m-d H:i:s')));
return ($success === TRUE) ? $this->sql->lastInsertId() : FALSE;
}
public function verifyCookie($token) {
$query = "SELECT userID
FROM sessions
WHERE token = :token
AND expires > NOW()";
$stmt = $this->sql->prepare($query);
$stmt->execute(array(':token' => $token));
return $stmt->fetchColumn();
}
}
?>Code: Select all
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) DEFAULT NULL AUTO_INCREMENT,
`username` varchar(30) DEFAULT NULL,
`password` varchar(60) DEFAULT NULL,
`email` varchar(100) DEFAULT NULL UNIQUE,
`created` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM;
CREATE TABLE IF NOT EXISTS `sessions` (
`id` int(11) DEFAULT NULL AUTO_INCREMENT,
`userID` int(10) DEFAULT NULL,
`token` varchar(50) DEFAULT NULL,
`expires` datetime DEFAULT NULL,
KEY `userID` (`id`,`userID`,`token`,`expires`),
KEY `token` (`id`,`userID`,`token`,`expires`),
PRIMARY KEY (`id`)
) ENGINE=MyISAM;I'm not sure about how hashPassword() works. Each user will have a different $salt and it will be the created date?
Re: Check my Code
They don't do the same thing at all. Validate checks once whether the user exists in the database and stores that in the exists property, which needs to be private. The exists() method returns the value of the exists property; you can see the value but you can't change it. Login authenticates the user.ibnclaudius wrote:I am not sure why have three functions doing basically the same thing: login(), validate(), exists()
Haven't even had time to give it much thought. I suppose storing the username in the cookie could work.ibnclaudius wrote:About the problem with the cookie, you have an idea about how to fix it?
You might be better off using InnoDB over MyISAM so you can cascade deletes. No point keeping a user's logins stored if the user no longer exists.
-
ibnclaudius
- Forum Newbie
- Posts: 12
- Joined: Thu Dec 08, 2011 7:41 pm
Re: Check my Code
Finally got the login(), validate(), exists() function..
About the cookie, I'm in the waiting.
Thanks!
About the cookie, I'm in the waiting.
Thanks!