and*_*ber 10 authentication cookies jsonp login cross-domain
如何让用户登录到一个域并自动登录到我的其他域,而无需在每个域上提交表单?
and*_*ber 16
我们都知道cookie不可跨域访问,因为这会带来安全风险.但是,使用一些技巧,有办法解决这个问题.基本上我们在中央域上为用户设置cookie,使用脚本检查该cookie的存在,然后使用JSON-P回调将该cookie复制到其他域.更详细:
步骤1
在<form>上显示mydomain.com(或myotherdomain.com等)应POST到central.com/login
第2步
打开central.com/login,验证用户名和密码,并在central.com域上设置包含该用户唯一值的cookie .然后将用户重定向回mydomain.com
SELECT unique_value FROM users WHERE username = $username
set cookie on central.com containing unique_value
Run Code Online (Sandbox Code Playgroud)
第3步
回到mydomain.com我们嵌入了一个javascript调用central.com/check.
<script type="text/javascript" src="http://central.com/check"></script>
Run Code Online (Sandbox Code Playgroud)
第4步
在central.com/check我们检查的唯一的Cookie设置为用户.然后我们嵌入了一个JavaScript回调(JSON-P),通知mydomain.com用户已登录.没有包含敏感的用户数据,否则hacker.com可以嵌入此脚本并获取用户的信息.(将适当的Access-Control标头设置为仅允许经过验证的域可以减轻此风险.)相反,我们会根据时间戳创建一次性哈希,以便mydomain.com验证身份验证.
if cookie on central.com is valid
user_data = array(
'success' => true,
'uid' => $uid,
'time' => time_stamp,
'hash' => disposable_salted_hash( $uid, time_stamp )
)
echo 'setDomainCookie(' . json_encode(user_data) . ')'
Run Code Online (Sandbox Code Playgroud)
第5步
然后执行回调函数,设置cookie mydomain.com.最后,我们可以刷新页面或仅使用他们登录的JavaScript(最好是两者)提醒用户.
function setDomainCookie( user_data ) {
if( user_data.success ) {
$.post('/setcookie', user_data, function() {
location.reload(true);
}
}
}
Run Code Online (Sandbox Code Playgroud)
mydomain.com/setcookie类似于第2步.当然这假设两个站点都可以访问相同的数据库(和代码)
if hash = disposable_salted_hash( $uid, time_stamp )
SELECT unique_value FROM users WHERE uid = $uid
set cookie on mydomain.com containing unique_value
Run Code Online (Sandbox Code Playgroud)
第6步
用户下次刷新页面时,我们可以绕过JSON-P回调
if cookie on mydomain.com is valid
loggedin = true
else
delete cookie on mydomain.com
proceed to Step 3
Run Code Online (Sandbox Code Playgroud)
第7步
mydomain.com应该去的链接central.com/logout
第8步
在central.com/logout,不仅删除了cookie,而且重置了该用户的唯一值.用户被重定向回mydomain.com
delete cookie on central.com
UPDATE users SET unique_value = new_random_value() WHERE username = $username
Run Code Online (Sandbox Code Playgroud)
第9步
现在重置了唯一值,从上面的步骤6失败,cookie也被删除mydomain.com,并且用户被有效地注销.
至关重要的是,central.com/check从步骤4开始设置正确的标头,以便它不被缓存.
用户登录时的步骤3-5可能会导致轻微延迟.刷新并显示他们登录的某种JavaScript警报是明智的.对于步骤3中的脚本尽可能接近页面顶部也很重要.
在步骤5中,您可以选择在每个域上存储唯一的cookie值.
单独的central.com域名并不是必需的; 如果您愿意,您可以使用其他域之一作为中心域.该域的逻辑显然会有所不同.
要使其在Internet Explorer上运行,您需要在cookie上附加P3P策略.
正如IvanGusev在评论中指出的那样,这种方法的一个缺陷是,如果用户退出设备A,它也会将其记录在每个其他设备之外.
希望这对人们有所帮助.我非常有兴趣收到反馈,特别是如果这种方法存在任何安全漏洞.我认为黑客可以做的最糟糕的事情就是重复步骤3-5并在mydomain.com你不知情的情况下登录,但那将是无害的.
| 归档时间: |
|
| 查看次数: |
9285 次 |
| 最近记录: |