文档章节

折衷的方式实现php与ruby共享session实现单点登录

游鱼彩虹
 游鱼彩虹
发布于 2016/12/15 17:04
字数 853
阅读 39
收藏 0

1.背景

前一阵部门要做一个内部讨论区,希望能和原有的gitlab集成在一起。

discuz虽然成熟但是感觉不够高大上,找了几个ruby的论坛discourse,rabel虽然时髦值够了但是成熟度又缺了点,最后选了php的question2answer作为论坛程序,采用iframe的方式嵌入原来的gitlab程序。

2.单点登录方案

2.1.共享cookie

  • 在cookie里保存user的信息,php读cookie并取得用户信息。
  • ruby和php程序要在同一个域名
  • cookie在客户端是可见的,一般要对cookie进行加密。
  • 数据不安全

2.2.共享session

  • 在cookie里保存ruby session信息,php获得session信息后读session数据。
  • ruby和php程序要在同一个域名
  • session内容客户端不可见。

2.3.cas

  • 通过统一认证服务登录
  • ruby和php登录时重定向至认证服务器,通过验证后回调相应服务保存token,之后只要具体服务向cas请求token是否过期就可以判断是否登录。

由于两个业务在同一个域名下,这里就放弃了复杂的cas方案;考虑源代码安全,没有用cookie存储用户信息,最后决定使用共享session的方式实现单点登录

3.通过session单点登录

3.1.rails与session

gitlab使用devise作为登录框架,关于session的配置在config/initilizers/sessions.rb下,默认使用redis方式保存session

Gitlab::Application.config.session_store(

  :redis_store, # Using the cookie_store would enable session replay attacks.

  servers: Gitlab::Application.config.cache_store.last, # re-use the Redis config from the Rails cache store

  key: '_gitlab_session',

  secure: Gitlab.config.gitlab.https,

  httponly: true,

  path: (Rails.application.config.relative_url_root.nil?) ? '/' : Rails.application.config.relative_url_root

)


这里也可以改成在数据库或者memcached里存储,存储格式与redis类似,不多讲了。

redis里key为session id,value为序列化后的数据,默认使用的序列化算法为marshal,理论上只要php读出内容来就可以取得session数据了。

3.2.ruby与序列化

不幸的是,php里没有能够直接反序列化marshal对象的的方法。

最初考虑把marshal改为json方式存储,需要修改redis-store的一些代码,主要是覆盖源代码中的marshal和unmarshal函数,替换为json实现。具体可以参考:Sharing Rails sessions with PHP, ColdFusion, and more!

不过用这个方法出现了一些问题:marshal序列话会保存对象的一些meta信息,json是没有这些信息的,导致反序列化之后的ruby对象与序列化之前不一样。

undefined method `sweep' for {"notice"=>"Logged in successfully."}:Hash

在网上搜索很久,一个日文的blog提出了解决方案:Rails sessionのシリアライズにJSONが使われない理由: なぜMarshal? JSON/YAMLの罠

主要是在反序列化的时候加了这么一句:

if original.has_key?('flash')
  original['flash'] = ActionDispatch::Flash::FlashHash.new.update(original['flash'])
end


3.3.折衷的方式

这么深度的修改对于这个需求似乎太复杂了,最后还是决定用简单些的方式,利用ruby开放一个session的json接口,php通过调用接口获得用户信息,修改的地方很少:

ruby

class ActiveController < ApplicationController

  def show
    render :json => current_user
  end

end


php

if ($_COOKIE['_gitlab_session']) {

   $ch = curl_init();

   curl_setopt($ch, CURLOPT_URL, "http://localhost:8080/active");

   curl_setopt($ch, CURLOPT_HEADER, 0);

   curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

   curl_setopt($ch, CURLOPT_COOKIE, '_gitlab_session='.$_COOKIE['_gitlab_session']);

   $filecontent=curl_exec($ch);

   curl_close($ch);

   $obj=json_decode($filecontent,true);

   // handle $obj

   //...

 

本文转载自:http://blog.2baxb.me/archives/827

游鱼彩虹
粉丝 9
博文 35
码字总数 2136
作品 0
荆州
程序员
私信 提问
phpcas 整合 ecms的问题

ecms是很多建站的开源cms选择之一,最近甲方提出一个额外需求是对接CAS框架实现SSO(单点登录) 关于单点登录原理,下面这篇博文是我见过,简介非常精简细致 单点登录原理分析 当下我的进度是...

南船座
2018/08/01
0
0
PHP单点登录

之前回答过同样的问题,我重新拿出来再回答一遍。题主请看 首先提醒一下题主不要被新技术吓到了,也不要去查什么SSO(Single Sign On,单点登录),那样只能增大你问题的复杂度和对这个问题的...

蜗牛奔跑
2016/11/20
50
0
SSO 单点登录总结(PHP)

本篇文章根据个人理解的知识整理汇总,如有不足之处,请大家多多指正。 单点登录(SSO——Single Sign On)的应用是很普遍的,尤其在大型网站系统中,比如百度,登录百度账号和,再转到百度经...

飞逸逸飞
2018/09/09
0
0
跨二级域单点登录解决方案[php+redis]

cookie共享 + session共享 cookie共享:共享同一个session cookie,服务端接受到相同的session id session共享:共享同一个session系统,这样来自不同二级域的统一session id访问同一会话数据...

big_cat
2015/11/09
0
0
集群下的session共享总结及问题

最近公司需要实现websphere集群的session共享,websphere集群本身支持共享,但是添加、删除节点还是需要重启服务才行(如果不是,请指正)。最近一直在骚扰@红薯 ,希望了解OSC的实现,现在也...

人头马没面
2012/12/08
9.1K
14

没有更多内容

加载失败,请刷新页面

加载更多

kotlin中奖概率

fun main() { var wins = 0 var chance = 0.2 var playTime = 10// 1000万次 val n = 10000000 (1..n).forEach { if (play(chance, playTime)) win......

oschina4cyy
23分钟前
1
0
第十一讲:爬取猫眼网站上的前100名电影

本次我们来通过翻页爬取的方式爬取猫眼电影里面推荐的前100名电影,并存储到数据库。 1、我们登录猫眼,看下我们的数据在哪里 然后点击今日TOP100,看下具体的网页数据 最下面我们看到底部有...

刘日辉
23分钟前
16
0
git 设置全局用户名/邮箱和某个项目用户名/邮箱/密码

一、特定项目设置用户名/邮箱/密码的方法 找到项目所在目录下的 .git,进入.git文件夹,然后执行如下命令分别设置用户名和邮箱 git config user.name "dawn.he" git config user.email "1...

hexiaoming123
23分钟前
0
0
好程序员分享Linux重器vi编辑器

创建练习文件 [root@tianyun ~]# ll -a > list.txt 文件编辑器 gedit 文件编辑器 vi, vim, nano vi编辑器工作模式 命令模式: a. 光标定位 hjkl 0 $ gg G 3G 进入第三行 /string (n N 可以循...

好程序员IT
24分钟前
2
0
Git整理(五) git cherry-pick的使用

概述 git cherry-pick可以理解为”挑拣”提交,它会获取某一个分支的单笔提交,并作为一个新的提交引入到你当前分支上。 当我们需要在本地合入其他分支的提交时,如果我们不想对整个分支进行...

嘿嘿嘿IT
32分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部