[英]Tab specific cookies without using sessionStorage or any HTML5 features
我感兴趣的是让用户能够在我的网络应用程序上登录并注销多个用户会话cookie。 目前,身份验证是标准的,并且唯一标识符允许我在用户访问我们的站点时对其进行身份验证,如果他们提供了cookie中可用的身份验证令牌。 典型用例适用于如果用户从一个选项卡注销,它会将其从另一个选项卡中注销。 现在,它要求用户从两个独特的浏览器实例登录,以便能够登录到两个不同的帐户。
是否有非HTML5方式(使用标准javascript cookie)具有特定于标签的cookie标识符? 我假设没有明确的方法来解决这个问题,这需要从后端进行某种黑客+合作。 如果有一个没有使用HTML5的解决方案,那将是理想的。
一段时间后我实现了类似的行为。 所以,我做的是这样的:
在此之前,只有您使用相对URL时,此解决方案才有效! (用于图像,链接甚至Ajax调用)
像在任何普通场景中一样使用会话进行一次小的更改。 您将通过每个会话ID识别一台机器(浏览器),而不是使用每个会话ID识别用户。 因此,当请求到达服务器时,它会识别在该计算机上使用您的网站的一群用户。 每个用户都有自己的子标识符(可以是顺序计数器或随机数)。 简单来说,您的会话数据(由Cookie中的会话ID标识)包含一个关联数组。 该阵列的每个条目保存由子标识符标识的一个特定用户的会话数据。 例如,在PHP中,如果您的用户的子标识符是user0
,那么您可以访问此用户的会话数据,如:
<?php
session_start();
$user_data = $_SESSION['user0'];
接下来是如何传递用户的子标识符。
您可以使用webserver的URL重写。 您需要提出一个可以被视为普通文件夹名称的模式,而没有像这样的文件夹。 例如:
RewriteEngine On
RewriteRule ^user(\d+)\/(.*)$ $2?sub_id=$1 [QSA,L]
在此示例中,您不允许使用user0
, user1
等任何文件夹。如果某些请求要求http://domain.com/user0/index.php
,则会将其重写为http://domain.com/index.php?sub_id=user0
。 现在在index.php
你将拥有:
<?php
session_start();
$user_data = $_SESSION[$_REQUEST['sub_id']];
从这一点开始你应该使用$user_data
而不是$_SESSION
。 唯一剩下的就是如何第一次生成子标识符。 这相对容易,您可以:
<?php
session_start();
if (!isset($_REQUEST['sub_id'])) {
$sub_id = 0;
while (isset($_SESSION["user{$sub_id}"])) {
$sub_id++;
}
$_SESSION["user{$sub_id}"] = array();
header("Location: /user{$sub_id}".$_SERVER['REQUEST_URI']);
die();
}
else {
$user_data = $_SESSION[$_REQUEST['sub_id']];
}
最后,只有当您的所有网址都是相对的时,一切都会有效! 不以/user0/
开头的每个绝对URL将被视为新用户,并将导致会话中的新条目。
这种方法的好处是,只要URL已经相对解决,您当前的代码将以最小的努力工作。
这是一个简单的示例,说明如何创建用户可以登录多个帐户的系统。 这不是安全检查,必须添加。 这段代码可以更好地编写和优化。
inc.php
https://github.com/maksa9/multiple-user-login/blob/master/inc.php
此文件包含在每个php脚本中。
此部分检查记录了哪个用户以及哪个帐户处于活动状态。 以下是根据活动帐户创建php脚本的正确路径的函数
// check which user is logged and which account is active
if(isset($_GET['user'])) $id_user = (int)$_GET['user'];
if($id_user > 0)
{
if(isset($_SESSION['user'][$id_user]))
{
$user_name = $_SESSION['user'][$id_user]['name'];
$user_email = $_SESSION['user'][$id_user]['email'];
}
else
gotToLoginForm();
}
// If the user id is not specified and there is a user session, finds another id
if($id_user == 0 and isset($_SESSION['user']))
{
$sess = $_SESSION['user'];
$id_user = (int)key($sess);
if(isset($_SESSION['user'][$id_user]))
{
$user_name = $_SESSION['user'][$id_user]['name'];
$user_email = $_SESSION['user'][$id_user]['email'];
define('ID_USER',$id_user);
gotToIndex();
}
else
gotToLoginForm();
}
define('ID_USER',$id_user);
loginform.php
https://github.com/maksa9/multiple-user-login/blob/master/loginform.php
使用post方法登录的简单表单。
的login.php
https://github.com/maksa9/multiple-user-login/blob/master/login.php
登录用户。 模拟对数据库的查询。
if(isset($_POST['email']))
if(isset($_POST['pass']))
{
$email = $_POST['email'];
$pass = $_POST['pass'];
$id_user = 0;
// simulates a query to the database
if($email === 'test1@test.com' and $pass === '111')
{
$id_user = 1;
$name='John Doe';
}
if($email === 'test2@test.com' and $pass === '222')
{
$id_user = 2;
$name = 'Doe John';
}
// login user
if($id_user > 0)
{
// checks if the user is already logged
if( !isset($_SESSION['user'][$id_user]))
{
$_SESSION['user'][$id_user] = array('email'=>$email, 'name'=>$name);
}
//go to main page
$page = ROOT.'user/'.$id_user.'/index.php';
header('Location: '.$page);
exit;
}
}
的index.php
https://github.com/maksa9/multiple-user-login/blob/master/index.php
应用程序的主页面。
<div>
<h1>Welcome: <?php echo $user_name ?> (<?php echo $user_email ?>) [<?php echo $id_user ?>]</h1>
<p><a href="<?php echo returnUrl('swap.php',$id_user) ?>">Choose an account</a></p>
<p><a href="<?php echo returnUrl('loginform.php',$id_user) ?>">Login with the another account</a></p>
<p><a href="<?php echo returnUrl('logout.php',$id_user) ?>">Log out</a></p>
</div>
swap.php
https://github.com/maksa9/multiple-user-login/blob/master/swap.php
允许用户选择帐户。
foreach($_SESSION['user'] as $idus => $userA)
{
echo '<p><a href="'.returnUrl('index.php',$idus).'">'.$userA['name'].' ('.$userA['email'].') ['.$idus.']</a></p>';
}
logout.php
https://github.com/maksa9/multiple-user-login/blob/master/logout.php
注销用户。 检查活动用户帐户并重定向(如果有)。
unset($_SESSION['user'][ID_USER]);
if(count($_SESSION['user']) == 0)
unset($_SESSION['user']);
// checks for active user accounts and redirects them if any
if(isset($_SESSION['user']))
{
$sess = $_SESSION['user'];
$id_user = (int)key($sess);
if(isset($_SESSION['user'][$id_user]))
{
$page = ROOT.'user/'.$id_user.'/index.php';
header('Location: '.$page);
exit;
}
}
的.htaccess
https://github.com/maksa9/multiple-user-login/blob/master/.htaccess
Options +FollowSymlinks
RewriteEngine On
RewriteRule ^user\/([0-9]*)\/index.php$ index.php?user=$1 [NC,L]
RewriteRule ^user\/([0-9]*)\/logout.php$ logout.php?user=$1 [NC,L]
RewriteRule ^user\/([0-9]*)\/login.php$ login.php?user=$1 [NC,L]
RewriteRule ^user\/([0-9]*)\/loginform.php$ loginform.php?user=$1 [NC,L]
RewriteRule ^user\/([0-9]*)\/swap.php$ swap.php?user=$1 [NC,L]
RewriteRule ^user\/$ index.php [NC,L]
RewriteRule ^user$ index.php [NC,L]
你不能
创建cookie时,可以通过设置其“根域”来控制其可见性。 然后,属于该根的任何URL都可以访问它。 例如,root可以设置为“example.com”,然后cookie将可用于“www.example.com”或“xyz.example.com”或“example.com”中的站点。 这可能用于允许相关页面相互“通信”。 无法将根域设置为“顶级”域,例如“.com”或“.co.uk”,因为这样可以广泛访问cookie。
默认情况下,cookie对其域中的所有路径都是可见的,但在创建时,它们可以被限制到给定的子路径 - 例如“www.example.com/images”。
所以任何具有相同根域的选项卡都可以访问该cookie。
会话cookie是服务器特定的AFAIK,因此您可以为同一服务器设置不同的DNS名称,例如子域名,如:session1.myserver.com,session2.myserver.com,session3.myserver.com
那么@ dm4web的回答是正确的,但你必须留意他的安全警告。 您可以做的最好的事情是采取双向方法。
方向一
Regular Login.
Create a Unique session ID and pass it via the URL.
方向二
Check Session via i) Logged In User and ii) Check Session ID via URL Param
现在,我们来举个例子:
$usrname: Fool
$psswd: dm4web
PHP代码
session_start();
//all inputs should be sanitized
$sql = "SELECT * FROM `users` WHERE `usrname`='".$usrname."' AND `psswd` = '".$psswd."'":
$dbh = new PDO('odbc:db', 'db2inst1', 'ibmdb2');
$count = $dbh->exec($sql);
if($count > 0){
//Guy is logged in
$a = session_id();
//**Use this $a in every URL parameter under current session**
}
else {
//Go f**k yourself >> to the user ;)
}
但是你应该注意到你不能直接跳转到那个用户/传递匹配方案。 首先,您必须确保了解用户是否已登录。 此外,基于PHP的SESSION Cookie,你可以理解这一点
您在所有情况下都匹配 URL参数,与SESSION cookie交叉引用并继续!
祝好运! 如果您还有其他问题,请与我们联系!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.