41
General Help & Support / Re: Wish list: "Remember me" at login...
« Last post by crnogorac081 on November 26, 2025, 08:02:07 PM »Hello,
Here Is how to Building a Secure Multi-Browser “Remember Me” System for WebsiteBaker using Help logic From Chatgtp
To create a **“remember me”** feature that works across **multiple browsers** and **multiple devices**, you should avoid browser fingerprinting (it’s unreliable and violates privacy standards).
The correct modern solution is to use a **persistent login token system** with a secure selector/validator mechanism.
Below is the complete implementation.
---
# **1. Create a Token Table**
Do not use the `remember_key` field in the `users` table.
Each device/browser needs its own token, so create a separate table:
```sql
CREATE TABLE IF NOT EXISTS `{TABLE_PREFIX}user_tokens` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`selector` char(16) NOT NULL,
`hashed_validator` char(64) NOT NULL,
`expires` int(11) NOT NULL,
`ip` varchar(45) NOT NULL DEFAULT '',
`user_agent` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
UNIQUE KEY (`selector`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
```
### Why two token parts?
A secure persistent login uses:
* **selector** → public part
* **validator** → private part (hashed in DB)
Cookie value looks like:
```
selector:validator
```
This prevents token theft/hijacking.
---
# **2. When User Logs In With “Remember Me”**
### (A) Generate token parts:
```php
$selector = bin2hex(random_bytes(
);
$validator = bin2hex(random_bytes(32));
$hashed_validator = hash('sha256', $validator);
$expires = time() + (86400 * 30); // 30 days
```
### (B) Insert token into database:
```php
$stmt = $db->prepare("INSERT INTO wb_user_tokens
(user_id, selector, hashed_validator, expires, ip, user_agent)
VALUES (?, ?, ?, ?, ?, ?)");
$stmt->execute([
$user_id,
$selector,
$hashed_validator,
$expires,
$_SERVER['REMOTE_ADDR'],
$_SERVER['HTTP_USER_AGENT']
]);
```
### (C) Set the cookie:
```php
setcookie(
"remember_me",
$selector . ':' . $validator,
$expires,
"/",
"",
true, // secure flag
true // httpOnly
);
```
This will work on **any browser and any device**.
---
# **3. Auto-Login When User Returns**
### (A) Check if the cookie exists:
```php
if (!empty($_COOKIE['remember_me'])) {
list($selector, $validator) = explode(':', $_COOKIE['remember_me']);
}
```
### (B) Find the token in database:
```php
$stmt = $db->prepare("SELECT user_id, hashed_validator, expires
FROM wb_user_tokens
WHERE selector = ? LIMIT 1");
$stmt->execute([$selector]);
$token = $stmt->fetch();
```
### (C) Validate expiration:
```php
if ($token['expires'] < time()) {
// Token expired — delete it from DB
}
```
### (D) Validate the validator:
```php
if (hash('sha256', $validator) === $token['hashed_validator']) {
// SUCCESS — log the user in
}
```
---
# **4. Token Rotation (Highly Recommended)**
After a successful auto-login:
1. Delete the old token
2. Generate and store a new one
This prevents replay attacks and increases security.
---
# **5. Optional: Limit Number of Active Devices**
To allow only the latest 5 devices, delete old ones:
```sql
DELETE FROM wb_user_tokens
WHERE user_id = ?
ORDER BY expires ASC
LIMIT 1;
```
---
# **6. Why Fingerprinting Is Not Recommended**
Browser fingerprinting is:
❌ inconsistent across browsers
❌ unstable (changes frequently)
❌ easily spoofed
❌ a privacy violation (GDPR)
Token-based authentication is the secure industry standard.
---
# **Final Result**
With this implementation you get:
✔ works on **all browsers**
✔ works on **multiple devices**
✔ secure tokens (hashed validators)
✔ based on OWASP security guidelines
✔ flexible — you can limit number of tokens per user
---
Secure Multi-Browser "Remember Me" System for WebsiteBaker
This post contains:
✔ Database table
✔ Complete explanation
✔ Full RememberMe.php class
✔ Login usage example
✔ Auto-login example
✔ Logout example
Everything below is ready for copy/paste.
1. Create the Token Table
Why selector + validator?
selector = public token
validator = private token (hashed in DB)
Stored cookie format:
2. RememberMe.php (FULL CLASS)
3. Login Script Example (with remember me)
4. Auto-Login on Every Page (init.php)
5. Logout (remove all tokens)
Done!
This system supports:
✔ Multiple browsers
✔ Multiple devices
✔ Secure hashed tokens
✔ Automatic token rotation
✔ OWASP-compliant persistent login
[/code]
Here Is how to Building a Secure Multi-Browser “Remember Me” System for WebsiteBaker using Help logic From Chatgtp
To create a **“remember me”** feature that works across **multiple browsers** and **multiple devices**, you should avoid browser fingerprinting (it’s unreliable and violates privacy standards).
The correct modern solution is to use a **persistent login token system** with a secure selector/validator mechanism.
Below is the complete implementation.
---
# **1. Create a Token Table**
Do not use the `remember_key` field in the `users` table.
Each device/browser needs its own token, so create a separate table:
```sql
CREATE TABLE IF NOT EXISTS `{TABLE_PREFIX}user_tokens` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`selector` char(16) NOT NULL,
`hashed_validator` char(64) NOT NULL,
`expires` int(11) NOT NULL,
`ip` varchar(45) NOT NULL DEFAULT '',
`user_agent` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
UNIQUE KEY (`selector`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
```
### Why two token parts?
A secure persistent login uses:
* **selector** → public part
* **validator** → private part (hashed in DB)
Cookie value looks like:
```
selector:validator
```
This prevents token theft/hijacking.
---
# **2. When User Logs In With “Remember Me”**
### (A) Generate token parts:
```php
$selector = bin2hex(random_bytes(
);$validator = bin2hex(random_bytes(32));
$hashed_validator = hash('sha256', $validator);
$expires = time() + (86400 * 30); // 30 days
```
### (B) Insert token into database:
```php
$stmt = $db->prepare("INSERT INTO wb_user_tokens
(user_id, selector, hashed_validator, expires, ip, user_agent)
VALUES (?, ?, ?, ?, ?, ?)");
$stmt->execute([
$user_id,
$selector,
$hashed_validator,
$expires,
$_SERVER['REMOTE_ADDR'],
$_SERVER['HTTP_USER_AGENT']
]);
```
### (C) Set the cookie:
```php
setcookie(
"remember_me",
$selector . ':' . $validator,
$expires,
"/",
"",
true, // secure flag
true // httpOnly
);
```
This will work on **any browser and any device**.
---
# **3. Auto-Login When User Returns**
### (A) Check if the cookie exists:
```php
if (!empty($_COOKIE['remember_me'])) {
list($selector, $validator) = explode(':', $_COOKIE['remember_me']);
}
```
### (B) Find the token in database:
```php
$stmt = $db->prepare("SELECT user_id, hashed_validator, expires
FROM wb_user_tokens
WHERE selector = ? LIMIT 1");
$stmt->execute([$selector]);
$token = $stmt->fetch();
```
### (C) Validate expiration:
```php
if ($token['expires'] < time()) {
// Token expired — delete it from DB
}
```
### (D) Validate the validator:
```php
if (hash('sha256', $validator) === $token['hashed_validator']) {
// SUCCESS — log the user in
}
```
---
# **4. Token Rotation (Highly Recommended)**
After a successful auto-login:
1. Delete the old token
2. Generate and store a new one
This prevents replay attacks and increases security.
---
# **5. Optional: Limit Number of Active Devices**
To allow only the latest 5 devices, delete old ones:
```sql
DELETE FROM wb_user_tokens
WHERE user_id = ?
ORDER BY expires ASC
LIMIT 1;
```
---
# **6. Why Fingerprinting Is Not Recommended**
Browser fingerprinting is:
❌ inconsistent across browsers
❌ unstable (changes frequently)
❌ easily spoofed
❌ a privacy violation (GDPR)
Token-based authentication is the secure industry standard.
---
# **Final Result**
With this implementation you get:
✔ works on **all browsers**
✔ works on **multiple devices**
✔ secure tokens (hashed validators)
✔ based on OWASP security guidelines
✔ flexible — you can limit number of tokens per user
---
Secure Multi-Browser "Remember Me" System for WebsiteBaker
This post contains:
✔ Database table
✔ Complete explanation
✔ Full RememberMe.php class
✔ Login usage example
✔ Auto-login example
✔ Logout example
Everything below is ready for copy/paste.
1. Create the Token Table
Code: [Select]
CREATE TABLE IF NOT EXISTS `wb_user_tokens` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`selector` char(16) NOT NULL,
`hashed_validator` char(64) NOT NULL,
`expires` int(11) NOT NULL,
`ip` varchar(45) NOT NULL DEFAULT '',
`user_agent` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
UNIQUE KEY (`selector`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Why selector + validator?
selector = public token
validator = private token (hashed in DB)
Stored cookie format:
Code: [Select]
selector:validator
2. RememberMe.php (FULL CLASS)
Code: [Select]
<?php
class RememberMe
{
private $db;
private $cookieName = "remember_me";
private $cookieLifetime = 86400 * 30; // 30 days
public function __construct($db)
{
$this->db = $db;
}
public function createToken($user_id)
{
$selector = bin2hex(random_bytes(8));
$validator = bin2hex(random_bytes(32));
$hashed_validator = hash('sha256', $validator);
$expires = time() + $this->cookieLifetime;
$stmt = $this->db->prepare("
INSERT INTO wb_user_tokens (user_id, selector, hashed_validator, expires, ip, user_agent)
VALUES (?, ?, ?, ?, ?, ?)
");
$stmt->execute([
$user_id,
$selector,
$hashed_validator,
$expires,
$_SERVER['REMOTE_ADDR'] ?? '',
$_SERVER['HTTP_USER_AGENT'] ?? ''
]);
setcookie(
$this->cookieName,
$selector . ":" . $validator,
$expires,
"/",
"",
true,
true
);
}
public function validateToken()
{
if (empty($_COOKIE[$this->cookieName])) {
return false;
}
list($selector, $validator) = explode(":", $_COOKIE[$this->cookieName]);
$stmt = $this->db->prepare("
SELECT id, user_id, hashed_validator, expires
FROM wb_user_tokens
WHERE selector = ?
LIMIT 1
");
$stmt->execute([$selector]);
$token = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$token) {
return false;
}
if ($token['expires'] < time()) {
$this->deleteTokenById($token['id']);
return false;
}
if (hash('sha256', $validator) !== $token['hashed_validator']) {
$this->deleteTokenById($token['id']);
return false;
}
$this->deleteTokenById($token['id']);
$this->createToken($token['user_id']);
return $token['user_id'];
}
private function deleteTokenById($id)
{
$stmt = $this->db->prepare("DELETE FROM wb_user_tokens WHERE id = ?");
$stmt->execute([$id]);
}
public function deleteTokensByUser($user_id)
{
$stmt = $this->db->prepare("DELETE FROM wb_user_tokens WHERE user_id = ?");
$stmt->execute([$user_id]);
setcookie($this->cookieName, "", time() - 3600, "/", "", true, true);
}
}
?>
3. Login Script Example (with remember me)
Code: [Select]
require 'RememberMe.php';
$remember = new RememberMe($db);
if ($login_successful) {
if (!empty($_POST['remember_me'])) {
$remember->createToken($user_id);
}
$_SESSION['user_id'] = $user_id;
// redirect to dashboard...
}
4. Auto-Login on Every Page (init.php)
Code: [Select]
require 'RememberMe.php';
$remember = new RememberMe($db);
if (empty($_SESSION['user_id'])) {
$user_id = $remember->validateToken();
if ($user_id !== false) {
$_SESSION['user_id'] = $user_id;
}
}
5. Logout (remove all tokens)
Code: [Select]
$remember = new RememberMe($db);
$remember->deleteTokensByUser($_SESSION['user_id']);
session_destroy();
Done!
This system supports:
✔ Multiple browsers
✔ Multiple devices
✔ Secure hashed tokens
✔ Automatic token rotation
✔ OWASP-compliant persistent login
[/code]
Support WebsiteBaker
Recent Posts

