aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvincent-peugnet <v.peugnet@free.fr>2020-05-15 20:05:26 +0200
committervincent-peugnet <v.peugnet@free.fr>2020-05-15 20:05:26 +0200
commitded1b2a19ee238543d561b6f26312458d2a43974 (patch)
treeb5569c95266ad7482298a7feffb6a3be24a19844
parent3f69df3b93510f2704f3af9d54b9bf3b34d0e6bb (diff)
downloadwcms-ded1b2a19ee238543d561b6f26312458d2a43974.tar.gz
wcms-ded1b2a19ee238543d561b6f26312458d2a43974.zip
new cookie session system
composer require JWT user stores sessions
-rw-r--r--app/class/Controller.php27
-rw-r--r--app/class/Controllerconnect.php49
-rw-r--r--app/class/Modelconnect.php45
-rw-r--r--app/class/Session.php6
-rw-r--r--app/class/User.php50
-rw-r--r--composer.json1
-rw-r--r--composer.lock53
7 files changed, 207 insertions, 24 deletions
diff --git a/app/class/Controller.php b/app/class/Controller.php
index 11a2c12..c631726 100644
--- a/app/class/Controller.php
+++ b/app/class/Controller.php
@@ -45,17 +45,30 @@ class Controller
public function setuser()
{
- if (empty($this->session->user)) {
- $this->user = new User();
- } else {
- if (!$this->user = $this->usermanager->get($this->session->user)) {
- if (!$this->user = $this->usermanager->readcookie()) {
- $this->user = new User();
+ // check session, then cookies
+ if (!empty($this->session->user)) {
+ $user = $this->usermanager->get($this->session->user);
+ } elseif (!empty($_COOKIE['authtoken'])) {
+ try {
+ $modelconnect = new Modelconnect();
+ $datas = $modelconnect->checkcookie();
+ $user = $this->usermanager->get($datas['userid']);
+ if ($user !== false && $user->checksession($datas['wsession'])) {
+ $this->session->addtosession("wsession", $datas['wsession']);
+ $this->session->addtosession("user", $datas['userid']);
} else {
- $this->session->addtosession('user', $this->user->id());
+ $user = false;
}
+ } catch (Exception $e) {
+ Model::sendflashmessage("Invalid Autentification cookie exist : $e", "warning");
}
}
+ // create visitor
+ if (empty($user)) {
+ $this->user = new User();
+ } else {
+ $this->user = $user;
+ }
}
public function initplates()
diff --git a/app/class/Controllerconnect.php b/app/class/Controllerconnect.php
index 8347a8f..4790c63 100644
--- a/app/class/Controllerconnect.php
+++ b/app/class/Controllerconnect.php
@@ -2,8 +2,12 @@
namespace Wcms;
+use RuntimeException;
+
class Controllerconnect extends Controller
{
+ /** @var Modelconnect */
+ protected $modelconnect;
public function log()
{
@@ -38,21 +42,36 @@ class Controllerconnect extends Controller
{
if (!empty($_POST['pass']) && !empty($_POST['user'])) {
$this->user = $this->usermanager->passwordcheck($_POST['user'], $_POST['pass']);
- if ($this->user != false) {
- if (
+ if (
+ $this->user != false
+ && (
$this->user->expiredate() === false
|| $this->user->level() === 10
|| $this->user->expiredate('date') > $this->now
- ) {
- $this->user->connectcounter();
- $this->usermanager->add($this->user);
- $this->session->addtosession('user', $this->user->id());
-
- if ($_POST['rememberme'] && $this->user->cookie() > 0) {
- $token = $this->createauthtoken();
- if ($token) {
- $_SESSION['user' . Config::basepath()]['authtoken'] = $token;
+ )
+ ) {
+ $this->user->connectcounter();
+ $this->usermanager->add($this->user);
+ $this->session->addtosession('user', $this->user->id());
+
+ if ($_POST['rememberme']) {
+ if ($this->user->cookie() > 0) {
+ try {
+ $this->modelconnect = new Modelconnect();
+ $wsession = $this->user->newsession();
+ $this->modelconnect->createauthcookie(
+ $this->user->id(),
+ $wsession,
+ $this->user->cookie()
+ );
+ $this->usermanager->add($this->user);
+ $this->session->addtosession('wsession', $wsession);
+ } catch (RuntimeException $e) {
+ Model::sendflashmessage("Can't create authentification cookie : $e", "warning");
}
+ } else {
+ $message = "Can't remember you beccause user cookie conservation time is set to 0 days";
+ Model::sendflashmessage($message, "warning");
}
}
}
@@ -66,11 +85,11 @@ class Controllerconnect extends Controller
public function logout($route, $id = null)
{
- $this->user = $this->usermanager->logout();
$this->session->addtosession('user', '');
- if (!empty($_SESSION['user' . Config::basepath()]['authtoken'])) {
- $this->destroyauthtoken($_SESSION['user' . Config::basepath()]['authtoken']);
- }
+ $this->user->destroysession($this->session->wsession);
+ $this->session->addtosession('wsession', '');
+ $this->usermanager->add($this->user);
+
if ($id !== null && $route !== 'home') {
$this->routedirect($route, ['page' => $id]);
} else {
diff --git a/app/class/Modelconnect.php b/app/class/Modelconnect.php
new file mode 100644
index 0000000..1201d36
--- /dev/null
+++ b/app/class/Modelconnect.php
@@ -0,0 +1,45 @@
+<?php
+
+namespace Wcms;
+
+use Firebase\JWT\JWT;
+use RuntimeException;
+use Exception;
+
+class Modelconnect extends Model
+{
+
+ /**
+ * @param string $userid
+ * @param string $wsession
+ * @param int $conservation
+ * @throws RuntimeException if secret key is not set or cant send cookie
+ */
+ public function createauthcookie(string $userid, string $wsession, int $conservation)
+ {
+ $datas = [
+ "userid" => $userid,
+ "wsession" => $wsession
+ ];
+ if (empty(Config::secretkey())) {
+ throw new RuntimeException("Secret Key not set");
+ }
+ $jwt = JWT::encode($datas, Config::secretkey());
+ $cookie = setcookie('authtoken', $jwt, time() + $conservation * 24 * 3600, "", "", false, true);
+ if (!$cookie) {
+ throw new RuntimeException("Cant be send");
+ }
+ }
+
+ /**
+ * Check cookie using JWT
+ * @throws Exception
+ */
+ public function checkcookie()
+ {
+ if (!empty($_COOKIE['authtoken'])) {
+ $datas = JWT::decode($_COOKIE['authtoken'], Config::secretkey(), ['HS256']);
+ return get_object_vars($datas);
+ }
+ }
+}
diff --git a/app/class/Session.php b/app/class/Session.php
index 64b6b26..5228237 100644
--- a/app/class/Session.php
+++ b/app/class/Session.php
@@ -12,6 +12,7 @@ class Session extends Item
public $showrightpanel = false;
public $homedisplay = 'list';
public $mediadisplay = 'list';
+ public $wsession = '';
public function __construct($datas = [])
{
@@ -78,4 +79,9 @@ class Session extends Item
$this->mediadisplay = $mediadisplay;
}
}
+
+ public function setwsession($wsession)
+ {
+ $this->wsession = $wsession;
+ }
}
diff --git a/app/class/User.php b/app/class/User.php
index e78c10c..d9339c8 100644
--- a/app/class/User.php
+++ b/app/class/User.php
@@ -19,6 +19,8 @@ class User extends Item
protected $expiredate = false;
/** @var Bookmark[] Associative array as `id => Bookmark`*/
protected $bookmark = [];
+ /** @var array sessions */
+ protected $sessions = [];
protected $display = ['bookmark' => false];
public function __construct($datas = [])
@@ -103,6 +105,11 @@ class User extends Item
return $this->bookmark;
}
+ public function sessions()
+ {
+ return $this->sessions;
+ }
+
public function display()
{
return $this->display;
@@ -218,6 +225,13 @@ class User extends Item
}
}
+ public function setsessions($sessions)
+ {
+ if (is_array($sessions)) {
+ $this->sessions = $sessions;
+ }
+ }
+
public function setdisplay($display)
{
if (is_array($display)) {
@@ -268,6 +282,42 @@ class User extends Item
return false;
}
+ /**
+ * Generate new unique session ID
+ * @param string $info session info to store
+ * @return string session key
+ */
+ public function newsession(string $info = "no_info"): string
+ {
+ $exist = true;
+ while ($exist === true) {
+ $session = bin2hex(random_bytes(10));
+ $exist = key_exists($session, $this->sessions());
+ }
+ $this->sessions[$session] = $info;
+ return $session;
+ }
+
+ /**
+ * Remove Session from user
+ * @param string $session session ID to remove
+ * @return bool true if session exist and was destroyed, false if key does not exist
+ */
+ public function destroysession(string $session): bool
+ {
+ if (key_exists($session, $this->sessions)) {
+ unset($this->sessions[$session]);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public function checksession(string $session): bool
+ {
+ return key_exists($session, $this->sessions);
+ }
+
public function isvisitor()
diff --git a/composer.json b/composer.json
index 95a2d94..dccf6ab 100644
--- a/composer.json
+++ b/composer.json
@@ -4,6 +4,7 @@
"require": {
"php": ">=7.2.0",
"altorouter/altorouter": "^1.2",
+ "firebase/php-jwt": "^5.2",
"jamesmoss/flywheel": "^0.5.2",
"league/plates": "^3.3",
"michelf/php-markdown": "^1.8"
diff --git a/composer.lock b/composer.lock
index 5606478..7d41d88 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "content-hash": "6da5a2cb510d9953dfe07df3411f9cd9",
+ "content-hash": "271a2f7b5c32b5641b02ea8f50d55f73",
"packages": [
{
"name": "altorouter/altorouter",
@@ -62,6 +62,56 @@
"time": "2015-11-30T00:47:43+00:00"
},
{
+ "name": "firebase/php-jwt",
+ "version": "v5.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/firebase/php-jwt.git",
+ "reference": "feb0e820b8436873675fd3aca04f3728eb2185cb"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/firebase/php-jwt/zipball/feb0e820b8436873675fd3aca04f3728eb2185cb",
+ "reference": "feb0e820b8436873675fd3aca04f3728eb2185cb",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": ">=4.8 <=9"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Firebase\\JWT\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Neuman Vong",
+ "email": "neuman+pear@twilio.com",
+ "role": "Developer"
+ },
+ {
+ "name": "Anant Narayanan",
+ "email": "anant@php.net",
+ "role": "Developer"
+ }
+ ],
+ "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.",
+ "homepage": "https://github.com/firebase/php-jwt",
+ "keywords": [
+ "jwt",
+ "php"
+ ],
+ "time": "2020-03-25T18:49:23+00:00"
+ },
+ {
"name": "jamesmoss/flywheel",
"version": "0.5.3",
"source": {
@@ -3359,7 +3409,6 @@
"psr",
"psr-7"
],
- "abandoned": "laminas/laminas-diactoros",
"time": "2019-11-13T19:16:13+00:00"
}
],