准备工作
有以下三个网站a.com b.com c.com等多个不同域名的子站,和公共的sso.com登录服务器
a.com b.com c.com需要在本域下分别暴露一个设置登录成功的cookie脚本和获取cookie的脚本。#a.com/set_cookie.php b.com/set_cookie.php c.com/set_cookie.php
#a.com/get_cookie.php b.com/get_cookie.php c.com/get_cookie.php
sso.com则需要设置白名单和子站set_cookie的地址
主要思路
用户登入网站,不管在a.com,b.com,c.com哪个域名下,如果需要登录,都重定向到sso.com登录服务器,0.登录a.com,异步请求a.com/get_cookie.php,如果没有则未登录,如需登录则跳转至sso.com登录服务器
1.sso.com登录服务器记录refer并检查是否在白名单内
2.检查sso.com域名下是否存在登录cookie
3.没有检查到登录cookie,展示登录表单,待用户输入账号密码
4.sso.com验证用户账号密码信息正确,生成唯一token,存入cookie,token写入redis对应好用户和token的关系
5.将token进行rsa对称加密传输,这里可以为其他加密方法,保证传输的安全不被窃取,通过script或iframe的加载a.com的set_ookie脚本,就是html页面加入一段script或iframe标签进行跨域访问
6.a.com的set_cookie脚本验证token.并将token写入cookie(重点:这里需要P3P头设置,设置方法在文章末尾)
7.此时,sso.com可以重定向到a.com此时a.com已经写入cookie成功,所以登录成功
8.从a.com登录b.com,同步骤0
9.此时sso.com已有cookie,继续验证token是否在redis存在,如果有,则进行步骤6
10.同6,设置cookie
11.同7,重定向已设置好cookie的b.com显示登录成功
这里主要是一个思路,安全性有待商榷,主要需要防止Cookie伪造和窃取。
p3p头设置//验证略过
//主要下面这个p3p头的设置,可以跨域读取cookie
header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"');
setcookie("ticket", $token, $expire_at, "/", ".");
后记
也可以在步骤7直接跳转set_cookie,让写入cookie脚本进行重定向,这样就不需要加p3p头和跨域访问了。
如果是同父域名就不需要这么麻烦,比如a.xx.com、b.xx.com,直接设置cookie的时候设置domain为父域下的所有子域即可,登录态用session,如果分布式系统,则考虑session第三方存储,如redis或memcached