日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > php >内容正文

php

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

發布時間:2025/4/16 php 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 折衷的方式实现php与ruby共享session实现单点登录 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

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 storekey: '_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 < ApplicationControllerdef showrender :json => current_userendend


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//...

?

轉載于:https://my.oschina.net/u/1189928/blog/806546

總結

以上是生活随笔為你收集整理的折衷的方式实现php与ruby共享session实现单点登录的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。