simple tokenized loginsystem

This commit is contained in:
Jarkko Toivanen 2024-09-28 08:21:52 +03:00
parent 8f2311df0b
commit f5371aba5d
Signed by: jt
GPG key ID: 9151B109B73ECAD5
5 changed files with 124 additions and 10 deletions

View file

@ -53,6 +53,15 @@ class DataBase extends SQLite3 {
FOREIGN KEY (personaid) REFERENCES personas(id) ON UPDATE CASCADE ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS tokens (
id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,
userid INTEGER NOT NULL,
token TEXT NOT NULL UNIQUE,
lastuse TEXT NOT NULL,
expires TEXT NOT NULL,
FOREIGN KEY (userid) REFERENCES users(id) ON UPDATE CASCADE ON DELETE CASCADE
);
INSERT OR IGNORE INTO users (id, handle, name, about) VALUES ('0', 'SYSTEM', 'SYSTEM', 'SYSTEM');
";
@ -70,6 +79,16 @@ class DataBase extends SQLite3 {
}
}
function getUserByHandle($handle) {
$handle = $this->escapeString($handle);
$sql = "SELECT * FROM users AS user WHERE handle='$handle';";
$ret = $this->query($sql)->fetchArray(SQLITE3_ASSOC);
if(!$ret) {
return false;
}
return $ret;
}
function addPost($text, $userid=NULL, $personaid=NULL) {
$id = hexdec(uniqid());
$time = time();
@ -109,6 +128,56 @@ class DataBase extends SQLite3 {
return password_verify($password, $dbhash);
}
function tokenGen() {
return random_bytes(32);
}
function tokenAdd($userid) {
$token = $this->tokenGen();
$hashed = hash('sha256', $token);
$time = time();
$expires = $time + 2592000; // 30 days
$sql = "INSERT INTO tokens (userid, token, lastuse, expires) VALUES ('$userid', '$hashed', '$time', '$expires');";
$ret = $this->exec($sql);
if(!$ret) {
die($this->lastErrorMsg());
}
return $token;
}
function tokenRefresh($tokenid) {
$time = time();
$expires = $time + 2592000; // 30 days
$sql = "UPDATE tokens SET lastuse='$time', expires='$expires' WHERE id='$tokenid';";
$ret = $this->exec($sql);
if(!$ret) {
die($this->lastErrorMsg());
}
}
function tokenRemove($token) {
$hashed = hash('sha256', $token);
$sql = "DELETE FROM tokens WHERE token='$hashed';";
$ret = $this->exec($sql);
if(!$ret) {
die($this->lastErrorMsg());
}
}
function getAuthedUserId($token=NULL) {
if (empty($token)) {
if (empty($_COOKIE['token'])) {
return false;
}
$token = base64_decode($_COOKIE['token']);
}
$hashed = hash('sha256', $token);
$sql = "SELECT id AS id, userid AS userid FROM tokens WHERE token='$hashed';";
$ret = $this->query($sql)->fetchArray(SQLITE3_ASSOC);
if(!$ret) {
return false;
}
$this->tokenRefresh($ret['id']);
return $ret['userid'];
}
function getPosts($userid=NULL, $personaid = NULL) {
$sql = "SELECT * FROM posts AS post LEFT JOIN users AS user ON post.userid=user.id LEFT JOIN personas AS persona ON post.personaid=persona.id;";

View file

@ -1,3 +1,10 @@
<?php
require_once "inc/database.php";
$database = new DataBase();
if(!$database) {
die($database->lastErrorMsg());
}
?>
<!DOCTYPE html>
<html>
<head>
@ -9,6 +16,21 @@
<body>
<div id="centerbox">
<div id="titlebox"><img src="favicon.ico" />Snuffler</div>
<?php
if (!$database->getAuthedUserId()) {
?>
<form id="loginform" method="post" action="login.php">
<input type="text" name="name" placeholder="username" />
<input type="password" name="pass" placeholder="password" />
<input type="submit" name="submit" value="Log in" />
</form>
<?php
} else {
?>
<a href="logout.php">LOG OUT</a>
<form id="postform">
<textarea id="postformtextarea" name="text" rows="5" placeholder="Whatcha snuffin' about?"></textarea><br />
<div id="postformactionrow">
@ -20,15 +42,12 @@
</div>
</form>
<?php
}
?>
<?php
require_once "inc/database.php";
$database = new DataBase();
if(!$database) {
die($database->lastErrorMsg());
}
//$database->addPost("Test post", 0);
@ -39,8 +58,8 @@ foreach($posts as $post) {
echo '<strong>' . $post["user.name"] . '</strong>';
echo '<br><small>@' . $post["user.handle"] . '</small>';
echo '<p>' . $post["post.text"] . '</p>';
echo '<hr><small>' . date("D j.n.Y \k\l\o G:i", $post["post.time"]) . '</small>';
echo '<span class="postactions">5👍 0👎 2💬</span>';
echo '<hr><small>' . date("D j.n.Y \@ G:i", $post["post.time"]) . '</small>';
echo '<span class="postactions">👍5 👎0 💬2</span>';
echo "</div>";
}

16
login.php Normal file
View file

@ -0,0 +1,16 @@
<?php
if (empty($_POST) || !isset($_POST['submit'])) {
die("Login canceled: no post / no submit");
}
require_once('inc/database.php');
$db = new DataBase();
$user = $db->getUserByHandle($_POST['name']);
if ($db->passwordVerify($user['user.id'], $_POST['pass'])) {
$token = $db->tokenAdd($user['user.id']);
$token64 = base64_encode($token);
$expires = time() + 2592000; // 30 days
setcookie('token', $token64, $expires);
}
header("Location: /");
?>

7
logout.php Normal file
View file

@ -0,0 +1,7 @@
<?php
setcookie("token", "", 0);
require_once('inc/database.php');
$db = new DataBase();
$db->tokenRemove(base64_decode($_COOKIE['token']));
header("Location: /");
?>

View file

@ -7,6 +7,9 @@ hr {
border-color: #584200;
}
#loginform {
text-align: center;
}
#titlebox {
font-size: 5em;
text-align: center;