Skip to content

Instantly share code, notes, and snippets.

@asifr
Last active August 29, 2015 14:13
Show Gist options
  • Select an option

  • Save asifr/8ed8ede755e6614837fc to your computer and use it in GitHub Desktop.

Select an option

Save asifr/8ed8ede755e6614837fc to your computer and use it in GitHub Desktop.
An email-based authentication system
$IsAuth = false;
$User = array();
// connect to database
try { $db = new PDO('sqlite:'.BASEPATH.DBNAME); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); } catch (PDOException $e) { die('Unable to open database. SQLite reported: '.$e->getMessage()); }
// create table if it doesn't already exist
if (count($db->query('SELECT 1 FROM sqlite_master WHERE name = \'users\' AND type=\'table\'')->fetchAll()) == 0) { $db->exec("CREATE TABLE users (id INTEGER NOT NULL,name VARCHAR(255) DEFAULT '',email VARCHAR(255) DEFAULT '',token VARCHAR(255) DEFAULT '',vars TEXT,created INTEGER,status INTEGER NOT NULL DEFAULT 0,PRIMARY KEY (id));"); }
// Set token for user and send email
if (token_validated("login") && isset($_POST['email']) && $_POST['email'] != '') {
$csrf_token = set_csrf_token();
$email = smartstripslashes($_POST['email']);
// $AllowedEmailAddressess can optionally limit new user registration
if (isset($AllowedEmailAddresses) && !empty($AllowedEmailAddresses)) {
if (!in_array($email, $AllowedEmailAddresses)) {
header("Location: ".$base_url."?login");
}
}
// generate a new token
$token = md5(str_shuffle(chr(mt_rand(32, 126)) . uniqid() . microtime(TRUE)));
if ($res = $db->query('SELECT * FROM users WHERE email='.$db->quote($email).';')) {
$user = $res->fetchAll(PDO::FETCH_ASSOC);
if (empty($user)) {
// New user
$q = $db->prepare('INSERT INTO users (email, token, created, status) VALUES (:email, :token, :created, :status)');
$q->execute(array(':email' => $email, ':token' => $token, ':status' => 0, ':created' => time()));
} else {
// Existing user
$q = $db->prepare('UPDATE users SET token=:token WHERE email=:email;');
$q->execute(array('token' => $token, 'email' => $email));
}
}
$login_url = sprintf("%s?login&email=%s&verify=%s,", $base_url.basename($_SERVER['SCRIPT_NAME']), urlencode($email), urlencode($token));
$message = sprintf($lang['login_message'], $login_url);
$headers[] = "From: ".SITE_EMAIL;
$headers[] = "Reply-To: ".SITE_EMAIL;
$headers[] = "X-Mailer: PHP/" . phpversion();
mail(SITE_EMAIL, SITE_TITLE.EMAIL_SUBJECT, $message, implode("\r\n", $headers));
header("Location: ".$base_url."?login&please-verify");
}
// Verify email and token exists, set a new token and change status
// the new token is what gets stored in a cookie and verified against the database
// the cookie is updated with each visit
if (isset($_GET['login']) && isset($_GET['email']) && $_GET['email'] != '' && isset($_GET['verify']) && $_GET['verify'] != '') {
$email = clean_str(urldecode($_GET['email']));
$token = clean_str(urldecode($_GET['verify']));
if ($res = $db->query('SELECT * FROM users WHERE email='.$db->quote($email).' AND token='.$db->quote($token).';')) {
$user = $res->fetchAll(PDO::FETCH_ASSOC);
if (!empty($user)) {
// Existing user
$token = md5(str_shuffle(chr(mt_rand(32, 126)) . uniqid() . microtime(TRUE)));
$q = $db->prepare('UPDATE users SET token=:token, status=:status WHERE id=:id;');
$q->execute(array('token' => $token, 'status' => 1, 'id' => $user[0]['id']));
generate_cookie($token);
header("Location: ".$base_url);
exit();
}
}
header("Location: ".$base_url."login");
exit();
}
if (isset($_GET['logout'])) {
logout();
}
load_user_from_cookie();
function generate_cookie($hash) {$path = '/'; $domain = preg_replace('/(^www\.|:\d+$)/', '', (!empty($_SERVER["HTTP_HOST"]) && $_SERVER["HTTP_HOST"]!=$_SERVER['SERVER_NAME'])?$_SERVER["HTTP_HOST"]:$_SERVER['SERVER_NAME']); $secure = false; setcookie(COOKIE_PREFIX.'Pass', $hash, (time() + ( 60 * 60 * 24 * 365)), $path, $domain, $secure); }
function logout() {$path = '/'; $domain = preg_replace('/(^www\.|:\d+$)/', '', (!empty($_SERVER["HTTP_HOST"]) && $_SERVER["HTTP_HOST"]!=$_SERVER['SERVER_NAME'])?$_SERVER["HTTP_HOST"]:$_SERVER['SERVER_NAME']); $secure = false; setcookie(COOKIE_PREFIX.'Pass', '', (time() - (60 * 60 * 24 * 365)), $path, $domain, $secure); unset($_COOKIE[COOKIE_PREFIX.'Pass']); }
function load_user_from_cookie() {global $IsAuth, $User, $db; if (isset($_COOKIE[COOKIE_PREFIX.'Pass']) && $_COOKIE[COOKIE_PREFIX.'Pass'] != '') {if ($res = $db->query('SELECT * FROM users WHERE token='.$db->quote($_COOKIE[COOKIE_PREFIX.'Pass']).';')) {$user = $res->fetchAll(PDO::FETCH_ASSOC); if (!empty($user)) {$User = $user[0]; $IsAuth = true; } } } }
function token_validated($action) { global $csrf_token; if (empty($_POST) || !isset($_POST['action']) || (isset($_POST['action']) && $_POST['action'] != $action)) {return false; } if (isset($_POST['token']) && $_POST['token'] != '' && $_POST['token'] == $csrf_token) {$csrf_token = set_csrf_token(); return true; } return false; }
$csrf_token = (isset($_SESSION['csrf_token']) && $_SESSION['csrf_token'] != '')?$_SESSION['csrf_token']:set_csrf_token();
function set_csrf_token() { return $_SESSION['csrf_token'] = $_GLOBALS['csrf_token'] = md5(str_shuffle(chr(mt_rand(32, 126)) . uniqid() . microtime(TRUE))); }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment