Created
March 22, 2010 13:09
-
-
Save Burgestrand/340058 to your computer and use it in GitHub Desktop.
Ett Auth-exempel med “kom ihåg mig”-funktion
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class Auth | |
{ | |
protected $_session; | |
protected static $_instance; | |
protected function __construct() | |
{ | |
// Hämta en sessionsinstans | |
$this->_session = Session::instance(); | |
// Auto-login | |
$this->auto_login(); | |
} | |
/** | |
* Skapar en instans eller returnerar en existerande instans av Auth | |
* | |
* @return Auth | |
*/ | |
public static function instance() | |
{ | |
if ( ! Auth::$_instance) | |
{ | |
Auth::$_instance = new Auth; | |
} | |
return Auth::$_instance; | |
} | |
/** | |
* Avslutar ett loginförsök genom att spara information i kaka och session | |
* | |
* @param array användarinformation | |
* @return Auth $this | |
*/ | |
protected function complete_login(Model_User $user, $remember = FALSE) | |
{ | |
if ($remember) | |
{ | |
// Skapa posten i databasen | |
$values = Model_User_Token::factory()->create($user->id)->values(); | |
// Skapa kakan | |
setcookie('auth_autologin_token', $values['token'], $values['expire']); | |
} | |
// Spara användaren | |
$this->_session->auth = $user->values(); | |
// En högre privilegienivå: generera nytt sessionsid | |
session_regenerate_id(); | |
return $this; | |
} | |
/** | |
* Försöker autologgain en användare baserat på en kaka. | |
* | |
* @return bool `true` om inloggningen lyckades | |
*/ | |
public function auto_login() | |
{ | |
// Kontrollera om token finns | |
if (empty($_COOKIE['auth_autologin_token'])) | |
{ | |
return FALSE; | |
} | |
$token = $_COOKIE['auth_autologin_token']; | |
// Kolla om den är giltig | |
$token = Model_User_Token::factory($token); | |
if ( ! $token->loaded()) | |
{ | |
// Finns inte eller har gått ut | |
return FALSE; | |
} | |
// Hämta användaren | |
$user = Model_User::factory($token->user_id); | |
// Skapa kaka och spara informationen i sessionen | |
$this->complete_login($user, TRUE); | |
return TRUE; | |
} | |
/** | |
* Returnerar sant om användaren är inloggad | |
* | |
* @return bool | |
*/ | |
public function logged_in() | |
{ | |
return isset($this->_session->auth); | |
} | |
/** | |
* Försöker logga in en användare med användarnamn och lösenord | |
* | |
* @param string username | |
* @param string password | |
* @param bool remember (default: false) | |
* @return bool | |
*/ | |
public function login($username, $password, $remember = FALSE) | |
{ | |
if ($this->logged_in()) | |
{ | |
trigger_error('Redan inloggad', E_USER_ERROR); | |
return FALSE; | |
} | |
// Hämta login-saltet för användaren | |
$user = Model_User::factory($username); | |
if ( ! $user->loaded()) | |
{ | |
// Hittade inte användaren | |
return FALSE; | |
} | |
// Hasha lösenordet och jämför | |
$password = sha1($user->salt . $password); | |
if ($password === $user->password) | |
{ | |
$this->complete_login($user, $remember); | |
return TRUE; | |
} | |
return FALSE; | |
} | |
/** | |
* Returnera användarinfo om inloggad, annars FALSE | |
* | |
* @return array|bool | |
*/ | |
public function get_user() | |
{ | |
if ($this->logged_in()) | |
{ | |
return $this->_session->auth; | |
} | |
return FALSE; | |
} | |
/** | |
* Loggar ut en inloggad användare | |
* | |
* @return bool lyckat | |
*/ | |
public function logout() | |
{ | |
// Radera sessiondatan | |
$this->_session->destroy(); | |
// Radera “kom ihåg”-kakan | |
unset($_COOKIE['auth_autologin_token']); | |
setcookie('auth_autologin_token', NULL, -86400); | |
return empty($this->_session->auth); | |
} | |
} | |
/* End of file auth.php */ | |
/* Location: ./classes/auth.php */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
require 'init.php'; | |
$auth = Auth::instance(); | |
if ($_POST) | |
{ | |
$post = $_POST + array( | |
'username' => '', | |
'password' => '', | |
'remember' => FALSE, | |
); | |
$username = $post['username']; | |
$password = $post['password']; | |
$remember = (bool) $post['remember']; | |
$auth->login($username, $password, $remember); | |
// Page refresh ftw | |
header("Location: " . $_SERVER['PHP_SELF']); | |
exit; | |
} | |
elseif (array_key_exists('logout', $_GET)) | |
{ | |
$auth->logout(); | |
header("Location: " . $_SERVER['PHP_SELF']); | |
exit; | |
} | |
?><!DOCTYPE html> | |
<html> | |
<head> | |
<meta http-equiv="Content-type" content="text/html;charset=utf-8"> | |
</head> | |
<body> | |
<?php if ($auth->logged_in()): ?> | |
<h1>Användarinfo</h1> | |
<pre><?php var_dump($auth->get_user()) ?></pre> | |
<p> | |
<a href="?logout">Logga ut</a> | |
</p> | |
<?php else: ?> | |
<form action="" method="POST"> | |
<dl> | |
<dt><label>Användarnamn: <input type="text" name="username"></label></dt> | |
<dd></dd> | |
<dt><label>Lösenord: <input type="text" name="password"></label></dt> | |
<dd></dd> | |
<dt><label>Kom ihåg mig: <input type="checkbox" name="remember"></label></dt> | |
<dd></dd> | |
</dl> | |
<p> | |
<input type="submit" value="Logga in"> | |
</p> | |
</form> | |
<?php endif; ?> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Startar sessionen | |
session_start(); | |
// Kopplar upp till MySQL | |
mysql_connect('localhost', 'test', 'test'); | |
mysql_select_db('test'); | |
// Registrerar en autoladdare för klasser | |
define('ROOT', dirname(__FILE__) . '/'); | |
function _autoload($class) | |
{ | |
$path = str_replace('_', '/', $class); | |
require ROOT . "classes/{$path}.php"; | |
} | |
spl_autoload_register('_autoload', TRUE); | |
/** | |
* En hjälpfunktion till MySQL | |
* | |
* @param string query | |
* @param array variabler (måste escapas!) | |
* @param resource link {@see mysql_query} | |
* @return array (associativ array av data) | |
*/ | |
function query($query, array $data = array(), $link = NULL) | |
{ | |
$result = call_user_func_array('mysql_query', array( | |
strtr($query, $data)) + (array) $link | |
); | |
if ( ! $result) | |
{ | |
trigger_error(mysql_error(), E_USER_ERROR); | |
} | |
if (is_bool($result)) | |
{ | |
return TRUE; | |
} | |
else | |
{ | |
$data = mysql_fetch_assoc($result) OR $data = array(); | |
return $data; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
abstract class Model | |
{ | |
protected $_data = array(), | |
$_state; | |
/** | |
* Konstruerar en modell med given data | |
* | |
* @param array data | |
*/ | |
protected function __construct(array $data = array()) | |
{ | |
$this->values($data); | |
! empty($data) AND $this->state('loaded'); | |
} | |
/** | |
* Getter/setter för modelldata | |
* | |
* @param array data | |
* @return this | |
*/ | |
public function values(array $data = array()) | |
{ | |
if (empty($data)) | |
{ | |
return $this->_data; | |
} | |
foreach ($data as $key => $value) | |
{ | |
$this->_data[$key] = $value; | |
} | |
return $this; | |
} | |
/** | |
* Laddar en modell med data utifrån en given kolumn | |
* | |
* @param string värde | |
* @return Model | |
*/ | |
public static function factory($value) | |
{ | |
trigger_error('Model::factory måste skapas i barnen', E_USER_ERROR); | |
} | |
/** | |
* Returnerar eller sätter modellens status | |
* | |
* @param mixed | |
* @return mixed|Model | |
*/ | |
public function state($state = NULL) | |
{ | |
if ($state !== NULL) | |
{ | |
$this->_state = $state; | |
return $this; | |
} | |
return $this->_state; | |
} | |
/** | |
* Returnerar sant om modellen är laddad | |
*/ | |
public function loaded() | |
{ | |
return $this->state() === 'loaded'; | |
} | |
/** | |
* Använd aldrig den här metoden någon annanstans om du inte vet vad du gör | |
* | |
* @param mixed | |
* @return mixed | |
*/ | |
protected static function escape($value) | |
{ | |
switch (gettype($value)) | |
{ | |
case 'boolean': | |
$value = $value ? 1 : 0; | |
break; | |
case 'integer': | |
case 'double': | |
$value = $value; | |
break; | |
case 'string': | |
$value = sprintf("'%s'", mysql_real_escape_string($value)); | |
break; | |
default: | |
trigger_error("Ogiltig typ i Model_User::escape", E_USER_ERROR); | |
} | |
return $value; | |
} | |
// Magiska PHP-funktioner, läs om dem i manualen | |
public function &__get($key) | |
{ | |
if ( ! isset($this->$key)) | |
{ | |
trigger_error(get_class($this) . "::{$key} existerar inte", E_USER_ERROR); | |
} | |
return $this->_data[$key]; | |
} | |
public function __set($key, $value) | |
{ | |
$this->values(array($key => $value)); | |
} | |
public function __isset($key) | |
{ | |
return array_key_exists($key, $this->_data); | |
} | |
} | |
/* End of file model.php */ | |
/* Location: ./classes/model.php */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CREATE TABLE `users` ( | |
`id` int(11) not null auto_increment, | |
`username` varchar(50) not null, | |
`password` char(40) not null, | |
`salt` char(40) not null, | |
PRIMARY KEY (`id`), | |
UNIQUE KEY (`username`) | |
) ENGINE=MyISAM DEFAULT CHARSET=utf8; | |
CREATE TABLE `user_tokens` ( | |
`token` char(40) not null, | |
`user_id` int(11) not null, | |
`expire` datetime not null, | |
PRIMARY KEY (`token`), | |
KEY `expire` (`expire`) | |
) ENGINE=MyISAM DEFAULT CHARSET=utf8; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class Session | |
{ | |
/** | |
* Startar en session om den inte redan har blivit startad | |
*/ | |
protected $_values; | |
protected function __construct() | |
{ | |
if ( ! session_id()) | |
{ | |
session_start(); | |
} | |
$this->_values = &$_SESSION; | |
} | |
/** | |
* Returnerar en instans av Session | |
* | |
* @return Session | |
*/ | |
public static function instance() | |
{ | |
return new Session; | |
} | |
/** | |
* Returnerar värdet på en nyckel, eller $default om det inte finns | |
* | |
* @param mixed $key | |
* @param mixed $default | |
* @return mixed | |
*/ | |
public function &get($key, $default = NULL) | |
{ | |
if ( ! isset($this->$key)) | |
{ | |
return $default; | |
} | |
return $this->$key; | |
} | |
/** | |
* Sätter värdet på en nyckel | |
* | |
* @param mixed key | |
* @param mixed value | |
* @return Session $this | |
*/ | |
public function set($key, $value) | |
{ | |
$this->$key = $value; | |
return $this; | |
} | |
/** | |
* Förstör en nuvarande session | |
*/ | |
public function destroy() | |
{ | |
$this->_values = $_SESSION = array(); | |
unset($_COOKIE[session_name()]); | |
return setcookie(session_name(), NULL, -86400); | |
} | |
// Magisk PHP-funktion, läs manualen | |
public function &__get($key) | |
{ | |
if ( ! isset($this->$key)) | |
{ | |
var_dump(debug_backtrace()); | |
trigger_error("Session::{$key} finns inte", E_USER_ERROR); | |
} | |
return $this->_values[$key]; | |
} | |
// Magisk PHP-funktion, läs manualen | |
public function __set($key, $value) | |
{ | |
$this->_values[$key] = $value; | |
} | |
// Magisk PHP-funktion, läs manualen | |
public function __isset($key) | |
{ | |
return array_key_exists($key, $this->_values); | |
} | |
} | |
/* End of file session.php */ | |
/* Location: ./classes/session.php */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class Model_User_Token extends Model | |
{ | |
/** | |
* Skapa en ny token i databasen | |
* | |
* @param int user id | |
* @param int utgångsdatum (default: nu +30 dagar) | |
* @return bool | |
*/ | |
public function create($user_id, $expire = NULL) | |
{ | |
// Skapa ny token | |
$token = sha1(uniqid('', TRUE)); | |
$expire = is_null($expire) ? strtotime('+30 days') : $expire; | |
$user_id = intval($user_id); | |
$result = query("INSERT INTO `user_tokens` (`token`, `user_id`, `expire`) VALUES (':token', :user_id, ':expire')", array( | |
':token' => mysql_real_escape_string($token), | |
':expire' => gmdate('Y-m-d H:i:s', $expire), | |
':user_id' => $user_id, | |
)); | |
$this->values(array('token' => $token, 'expire' => $expire, 'user_id' => $user_id)); | |
$this->state('loaded'); | |
return $this; | |
} | |
/** | |
* @param string token | |
*/ | |
protected function __construct($token = NULL) | |
{ | |
if ($token) | |
{ | |
$data = query("SELECT * FROM `user_tokens` WHERE `token` = ':token' AND `expire` > ':expire'", array( | |
':token' => mysql_real_escape_string($token), | |
':expire' => gmdate('Y-m-d H:i:s'), | |
)); | |
} | |
else | |
{ | |
$data = array(); | |
} | |
parent::__construct($data); | |
} | |
/** | |
* @param string token | |
* @return Model_User_Token | |
*/ | |
public static function factory($token = NULL) | |
{ | |
return new Model_User_Token($token); | |
} | |
} | |
/* End of file token.php */ | |
/* Location: ./classes/model/user/token.php */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class Model_User extends Model | |
{ | |
/** | |
* Kan ladda en användare utifrån användarnamn eller ID | |
* | |
* @param mixed id|username | |
* @return Model_User | |
*/ | |
public static function factory($value) | |
{ | |
$data = query("SELECT * FROM `users` WHERE `:column` = :value", array( | |
':column' => Model_User::get_column($value), | |
':value' => Model::escape($value), | |
)); | |
return new Model_User($data); | |
} | |
/** | |
* Hämta kolumn utifrån ett värde | |
* | |
* @param mixed | |
* @return string | |
*/ | |
protected static function get_column($value) | |
{ | |
if (is_numeric($value)) | |
{ | |
return 'id'; | |
} | |
else | |
{ | |
return 'username'; | |
} | |
} | |
} | |
/* End of file user.php */ | |
/* Location: ./classes/model/user.php */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment