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 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'); 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) { function addPost($text, $userid=NULL, $personaid=NULL) {
$id = hexdec(uniqid()); $id = hexdec(uniqid());
$time = time(); $time = time();
@ -109,6 +128,56 @@ class DataBase extends SQLite3 {
return password_verify($password, $dbhash); 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) { 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;"; $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> <!DOCTYPE html>
<html> <html>
<head> <head>
@ -9,6 +16,21 @@
<body> <body>
<div id="centerbox"> <div id="centerbox">
<div id="titlebox"><img src="favicon.ico" />Snuffler</div> <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"> <form id="postform">
<textarea id="postformtextarea" name="text" rows="5" placeholder="Whatcha snuffin' about?"></textarea><br /> <textarea id="postformtextarea" name="text" rows="5" placeholder="Whatcha snuffin' about?"></textarea><br />
<div id="postformactionrow"> <div id="postformactionrow">
@ -20,15 +42,12 @@
</div> </div>
</form> </form>
<?php
}
?>
<?php <?php
require_once "inc/database.php";
$database = new DataBase();
if(!$database) {
die($database->lastErrorMsg());
}
//$database->addPost("Test post", 0); //$database->addPost("Test post", 0);
@ -39,8 +58,8 @@ foreach($posts as $post) {
echo '<strong>' . $post["user.name"] . '</strong>'; echo '<strong>' . $post["user.name"] . '</strong>';
echo '<br><small>@' . $post["user.handle"] . '</small>'; echo '<br><small>@' . $post["user.handle"] . '</small>';
echo '<p>' . $post["post.text"] . '</p>'; echo '<p>' . $post["post.text"] . '</p>';
echo '<hr><small>' . date("D j.n.Y \k\l\o G:i", $post["post.time"]) . '</small>'; echo '<hr><small>' . date("D j.n.Y \@ G:i", $post["post.time"]) . '</small>';
echo '<span class="postactions">5👍 0👎 2💬</span>'; echo '<span class="postactions">👍5 👎0 💬2</span>';
echo "</div>"; 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; border-color: #584200;
} }
#loginform {
text-align: center;
}
#titlebox { #titlebox {
font-size: 5em; font-size: 5em;
text-align: center; text-align: center;