💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
**定义:**单点登录,即SSO。是在多个应用系统中,用户只需要登陆一次就可以访问所有相互信任的应用系 统。 **为什么要单点登录?** 先说一下这样做的好处吧,先来三个屌丝域名: www.abc.com m.abc.com n.abc.com 大家都知道,虽然他们都是一个域名但主机名不同,依然不能共享cookie(没有设置到域名.openpoor.com),这就导致用户在这些域名之间切换的时候需要重新登录,这是不能忍受的,所以需要同步登录。即一处登录,处处登录。 **案例设计:**在本地服务器测试。同一IP下,不同端口来实现不同站点之间的一次性登录,但是相同IP下会出现session冲突,不过还好,可以通过`ini_set('session.name', 'phpsessid1');`来解决不同端口之间的session冲突问题。具体看【[解决同IP下Session冲突](288242)】。出于最简单的案例展示,只做登录a站点后,b站点也登录。b站点登录,a站点登录,注销这些思路一样,不在做介绍。 **解决思路:** 假设有A站,B站。登录A站访问B站,B站也已经登录。 1.在A站首页(index.php)检测用户是否已经登录。如果已经登录,则显示:你已经登录首页。如果未登录,则返回一个A站登录页的(login.php)链接。 2.在A站登录页中。有个登录表单,可以提交用户名,密码。根据验证规则,检测用户输入的账号和密码是否正确。如果验证成功,则将A站的用户名保存到登录session。说明用户已经在A站登录。同时,页面跳转到A站同步登录页(sync.php),并且将A站用户名通过Des加密,发送给sync.php。 3.在sync.php中,通过js请求的方式,分别请求所有要登录的子站的同步登录页(slogin.php),并且将被加密的用户名传递给他。请求结束后,跳回A站首页。 4.B站的slogin.php。将获取传递过来的被加密的用户名解码传递给用户sesson。 在给B站赋值session的时候,必须遵从P3P标准。不然可能会创建session失败。 5.访问B站的时候,将不会再出现登录。 **资料:P3P**是一种被称为个人隐私安全平台项目(the Platform for Privacy Preferences)的标准,能够保护在线隐私权,使Internet冲浪者可以选择在浏览网页时,是否被第三方收集并利用自己的个人信息。如果一个站点不遵守P3P标准的话,那么有关它的Cookies将被自动拒绝,并且P3P还能够自动识破多种Cookies的嵌入方式。p3p是由全球资讯联盟网所开发的。 代码实现: A站index.php ~~~ <?php session_start(); ini_set('session.name', 'phpsessid1'); // s1 为总服务台,登录后,子站c也登录了 if (empty($_SESSION['username'])) { echo "您还未登录,<a href='/login.php'>请登录!</a>"; } else{ echo "您好,".$_SESSION['username']."您已经登录了本系统。<a href='/logout.php'>注销</a>"; } ?> ~~~ A站login.php ~~~ <?php session_start(); ?> <form action="" method="POST" style="text-align: center;"> 用户名:<input type="text" name="username"> 密码:<input type="text" name="password">&nbsp;&nbsp;<input type="submit" name="submit" value="登录"> </form> <?php if ($_POST['submit']) { if ($_POST['username']=="admin" and $_POST['password']=="admin") { // 登录成功,通知事务 require __DIR__.'/Des.php'; $_SESSION['username'] = $_POST['username']; $redirect = '/s1.php'; header('Location:/sync.php?redirect='.urlencode($redirect).'&code='.Des::encrypt($_POST['username'],'openpoor')); exit; } } ?> ~~~ A站sync.php ~~~ <?php // 获取所有的数据 $redirect = empty($_GET['redirect']) ? 'http://localhost:9013' : $_GET['redirect']; if(empty($_GET['code'])){ header('Loaction:http://'.urldecode($redirect)); exit; } $apps=array( "http://localhost:9012/sync.php", ); ?> <?php foreach ($apps as $row): ?> <script type="text/javascript" src="<?php echo $row?>?code='.$_GET['code']";>"></script> <?php endforeach ?> <script type="text/javascript"> window.onload=function(){ location.replace('<?php echo $redirect; ?>'); } </script> ~~~ B站slogin.php ~~~ <?php session_start(); header('Content-Type:text/javascript; charset=utf-8'); if(!empty($_GET['code'])){ require __DIR__.'/Des.php'; $username = Des::decrypt($_GET['code'],'openpoor'); if(!empty($username)){ header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"'); $_SESSION['username'] = $username; } } echo "function _(){window.status='ok';}";//这里只是随便返回 ~~~ B站首页 index.php ~~~ <?php session_start(); ini_set('session.name', 'phpsessid2'); if (empty($_SESSION['username'])) { echo "您还未登录,<a href='/slogin.php'>请登录!</a>"; } else{ echo "您好,".$_SESSION['username']."您已经登录了本系统。<a href='/logout.php'>注销</a>"; } ~~~