设为首页 收藏本站
查看: 835|回复: 0

[经验分享] SSO单点登录PHP简单版

[复制链接]

尚未签到

发表于 2017-12-29 12:48:01 | 显示全部楼层 |阅读模式
  前面做了一个新项目,需要用户资源可以需要共享。由于之前没有做过这样的东西,回家之后,立马网站百度“单点登录”。帖子很多,甄别之后,这里列几篇认为比较有营养。
  http://blog.csdn.net/ghsau/article/details/20545513,http://blog.sina.com.cn/s/blog_5f66526e0102vf43.html
  如果要解决两个网站之间的同步登录(单点登录)问题,首先来看看一个网站的登录问题。
  很多人知道一个网站的登录问题,PHP不就是把通过$_SESSION['user']=array('username'=>'user1');那么,看看php的一句代码,做了那些操作。以windows下wamp环境配合php的配置文件php.ini看瞧瞧session的相关知识?
  php中默认提供session处理方案,可以在php.ini配置文件中看到有这么两行,
  session.save_handler=file
  session.save_path = "E:/wamp/tmp",如下图
DSC0000.png

  这两句告诉我们,在php中session的处理是文件files的方式,存储的地方是E:/wamp/tmp,看看我的文件目录下去
DSC0001.png

  好啦,这就是传说中的session,看得着,点得鸟。可以用记事本打开下,可以看到是一些字符,这是php对象数组序列化之后的字符串。就是把session对象序列化之后,写到文件中,达到session的持久化。如果采用默认配置的话,多个网站的session文件都是存在一个地方的。也就是说,如果同一台服务器中,有两个网站,网站a和网站b的session文件都会存储在一个地方,session文件都有自己的唯一标示符,sessionID。sessionID的生成,sessionID是唯一的,这个sessionID跟session的持久化文件名称是对应的。php通过sessionID去获取session文件,反序列化出来,就能达到session读取的功能了。这样的话,会不会想到,如果两个sessionID相同的话,用户在网站a登录了,用户在去访问网站b的时候,如果sessionID相同,就是已经的登录的状态了。
  解决:两个网站sessionID相同思路
  php提供了session_id()这个函数可以获取到sessionID,可以设置sessionID。在原生PHP中,能实现通过session_id()去修改sessionID,在一些框架中比较难实现,需要深究框架代码,为何难实现呢,这里要了解session_id()和session_start()一些关联了,需要先设定sessionID之后,再去session_start()。所以在框架中,会自动的启用session_start(),所以在启动之后再去修改,sessionID未被修改。
  sessionID相同的还有一种方式,就是浏览器修改sessionID,sessionID是存储在cookie中,在配置文件中,可以看到session.name = PHPSESSID,那么这个PHPSESSID就是sessionID在cookie中的name了。如下图
DSC0002.png

  浏览器和服务器之间每次交互,这个cookie值都会传递给服务器,所以如果我们前台去修改这个值的话,就可以让两个网站公用一个sessionID的值了。
  具体实施:在网站b所有的页面用户加载的时候,去请求网站a的一个接口,看看用户是否有登录,如果有的话,就放回sessionID给网站b,网站b接受到sessionID之后,就修改浏览器cookie中的PHPSESSID值。这样网站b的用户再去操作的话,就会发现自己sessionID对应的session文件跟网站a是同一个,从而达到同步登录。
  网站b代码需要做的就是页面每次访问都需要去请求a网站的数据判断用户是否在a网站登录。
  

<if condition="!session('?member')">  
<!--未登录-->
  
<script type="text/javascript">
  function setCookie(name,value)
  {
  document.cookie = name + "="+ escape (value)+";path=/";
  }
  //jsonp登录函数
  function jsonp_do(data)
  {
  //log('');
  
    }
  <{~$t=time()}>
  $(document).ready(function(){
  $.ajax({
  type:'get',
  url:"<{:C('SSO_Site')}>?_ts=<{$t}>&_token=<{:md5($t.C('SecretKey'))}>",
  dataType:'jsonp',
  crossDomain: true,
  jsonp: "callback",
  jsonpCallback:'jsonp_do',
  success:function(data){
  if(data.error==0){
  setCookie('PHPSESSID',data.sess_id);
  }
  },
  error: function(XHR, textStatus, errorThrown){
  //log
  
        }
  });
  });
  
</script>
  
</if>
  

  那么网站a就要给出对应的页面来给网站b请求且返回数据。
  

/**  * [index 用户登录]
  * @Author:wty
  * @DateTime:2016年12月12日11:22:02
  * @return [type] [description]
*/  public function index()
  {
  //可以适当加入用户ip作为加密因子和浏览器因数
  $token=I('get._token');//加密串
  $timespan=I('get._ts');//时间时间戳
  $referer=$_SERVER['HTTP_REFERER'];//这里可以限定安全网址
  $error=100;
  //这里需要配置
  $allow=C('Allow_Site');
  if(($referer,$allow)){//如果是在允许访问列表里面
  $error=1;
  if($token&&$timespan){
  $error=2;
  $secretKey=C('SecretKey');//秘钥
  $check=($timespan.$secretKey);
  if($check==$token){
  $error=3;
  if(session('?member')){
  $error=0;
  $return=array('error'=>0,'username'=>session('member.username'),'sess_id'=>());
  echo  'jsonp_do('.json_encode($return).')';
  exit;
  }
  }
  }
  }
  echo  'jsonp_do('.json_encode(array('error'=>$error)).')';
  }
  

  现在多数网站都会采用到负载均衡多服务器,如果是多服务器的话,session的存储可以考虑的memcached或者redis中,上面说道php对于session的默认存储方式是files,如果用memcached的话,就要修改配置文件php.ini
  session.save_handler=memcached
  session.save_path = "tpc://192.168.1.1"
  在save_handler=memcached或者memcache这里,有点区别,如果配置写的是memcached的话,下面的save_path就要写tcp://192.168.1.1:11211,如果是memcache的话,save_path就要填写为192.168.1.1:11211
  差别不大。
  至此简单版本的单点登录基本完成了。
  更多原创博客请看个人独立博客:传送门

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-429331-1-1.html 上篇帖子: php 接口与前端数据交互实现 下篇帖子: php专业面试总结
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表