您好,登錄后才能下訂單哦!
本篇文章為大家展示了如何在PHP中使用cookie實現跨域session共享,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
設置cookie無效
setcookie("sso", "e589hR6VnO8K1CNQZ4PSP/LWGBhRKE5VckawQwl1TdE8d4Q5E7tW", 900);
這個問題很多剛入門php的小伙們都會碰到。這個代碼的本意應當是想設置cookie sso的有效期為15分鐘,可是執行這個代碼后發現沒有效果。為什么呢?因為第三個參數expire表示的是過期的時間節點,而不是有效時間,所以如果希望設置cookie為15分鐘,正確的做法應當是獲取當前的時間戳加上15分鐘。
setcookie這個函數還有path、domain參數都比較常用,強烈建議剛學php的小伙們多翻閱手冊。php手冊地址: http://php.net/manual/zh/index.php
獲取cookie值獲取不到
先看這樣一段代碼
setcookie("sso", "e589hR6VnO8K1CNQZ4PSP/LWGBhRKE5VckawQwl1TdE8d4Q5E7tW", time() + 900); var_dump($_COOKIE["sso"]);
要解決這個問題,要先了解一下setcookie后發生了什么?因為cookie是保存在客戶端的,php是服務端語言,實際上setcookie之后只是在返回的http頭增加一個cookie的頭信息,告訴客戶端需要設置一個醬紫的cookie,如下圖:
php中setcookie返回的http頭
而$_COOKIE這個數組里面保存客戶端傳遞上來的cookie。自然第一次刷新的時候因為客戶端沒有相應的cookie值,所以$_COOKIE是沒有sso的信息的。第一次請求過后,因為服務器設置了cookie sso,所以第一次請求過來客戶端就有了cookie sso的信息,所以第二次請求的時候就會帶上sso的信息,服務端就能通過$_COOKIE取到值了。
cookie跨域問題
這個可以說是cookie中一個比較熱門的問題,面試的時候一般很愛聊這方面的問題。
跨域的業務需求大概是醬紫:用戶在a.com進行了登錄,希望在b.com也同步進行了登錄。如果是同一個主域比較簡單,可以通過setcookie中的domain參數進行設定:例如有x.a.com和xx.a.com,可以通過設置domain為a.com,從而a.com的所有二級域名都可以共享這一個cookie。基于安全方面的原因,在a.com下面設置domain為b.com是無效的。
那么是否真的沒有辦法可以實現這個了呢?這個還是有一些奇巧淫技的,這里介紹一種使用內框iframe的方法。
具體思路:在a.com下設置cookie后,嵌入一個iframe框鏈接b.com的頁面,b.com設置好頁面cookie后,再嵌入一個a.com的頁面,然后通過parent.parent就可以調用最外層的a.com的js方法,從而進行跳轉或者一些其它的操作。具體代碼示例如下:
假設a.com有頁面:login.php和callback.php,b.com有頁面synclogin.php
a.com的login.php代碼:
<?php $sso = "e589hR6VnO8K1CNQZ4PSP/LWGBhRKE5VckawQwl1TdE8d4Q5E7tW"; setcookie("sso", $sso); ?> login success... <script type="text/javascript"> function jumpTo() { location.href = "http://a.com"; } </script> <iframe src="http://b.com/synclogin.php?sso=<?php echo $sso; ?>"></iframe>
b.com的synclogin.php頁面
<?php setcookie("sso", $_GET["sso"]); ?> <iframe src="http://a.com/callback.php"></iframe>
a.com的callback.php頁面
<script type="text/javascript"> parent.parent.jumpTo(); </script>
代碼看起來也不難,值得一提的是這里嵌入了兩個iframe,因為如果只用一個iframe的話,即在b.com的synclogin.php內直接調用父窗體的jumpTo方法,在有些瀏覽器下會提示沒有權限的錯誤:
Error: Permission denied to access property
這里只是演示了cookie跨域同步的思路,具體細節還有很多可以改進的地方,比如iframe鏈接的頁面可以考慮改成靜態的頁面,這樣效率會比php動態頁面快很多,還有像參數校驗、多個主域(比如還有c.om)同時登錄等等,這里就不再累述。
cookie的總結到這里就結束,如果你感覺有一些收獲,可以在頁面底部掃碼給我打賞喲,感謝O(∩_∩)O~
session
$_SESSION
沒有值
這個session使用和cookie有一點不太一樣,session使用前必須先調用session_start
方法。否則會收到一個undefined的錯誤:
Notice: Undefined variable: _SESSION
session存儲在哪
session存儲在服務端,但是session究竟是存儲在哪呢?php.ini中關于session有一個save_path的選項可以設置存放的目錄,如果這個選項沒有設置值,那么就存儲在系統默認的tmp目錄下。默認的tmp目錄可以通過sys_get_temp_dir方法取到。
例如在mac下面,php的session一般會存儲在/var/tmp目錄下。
session_start(); echo session_id();//本例輸出ipkl446enhae25uq92c28u4lo3 $_SESSION['name'] = "tony”; $_SESSION['users'] = array("tony", "andy");
通過session_id方法可以取到當前的session編號,通過這個編號可查看一下該session文件。
$ sudo more /var/tmp/sess_ipkl446enhae25uq92c28u4lo3 name|s:4:"tony";users|a:2:{i:0;s:4:"tony";i:1;s:4:"andy";}
可以清楚的看到session存儲數據的結構,其中值是用序列化的方式進行轉化存儲的。
session也用了cookie
session不是存儲在服務端嗎,怎么又和cookie扯上關系了?其實想想也簡單,因為客戶端再請求的時候,服務端怎么樣才能知道該客戶端的session存儲在哪個文件呢?其實也是通過cookie PHPSESSID來進行標識。
php中session的cookie標識
php在進行session操作的時候會生成一個session id,而后把這個值以cookie的形式保存在客戶端,就是圖示中的PHPSESSID了。客戶端在下次請求的時候就會帶上這個PHPSESSID,服務端就能知道當前客戶端對應的session文件了
session超時設置
cookie超時設置比較簡單,一個參數就搞定了。session這邊有點小麻煩,既不能單獨設置cookie PHPSESSID的超時時間,也不能單獨設置服務端文件的超時時間。具體的可以參考鳥哥這篇文章:如何設置一個嚴格30分鐘過期的Session,真的非常嚴謹,贊一下。
session服務器共享
這個問題和cookie的跨域類似,面試的時候也很愛聊這個問題。
以前在做服務器集群的時候會碰到這樣的一樣問題,就是用戶一會訪問是處于正常登錄狀態,一會訪問又沒有登錄了。這個問題偶爾才會出現。跟蹤代碼下去才發現session沒有取到相應的值,想想也是醉了:原來服務器session沒有設置共享,session存在在本地文件目錄,當用戶訪問另外一臺服務器的時候自然就取不到session了。
解決方法也不難,通過共享的存儲在進行服務器之間的共享。這里使用redis的進行session存儲。可以通過php.ini配置文件進行調整,也可以在代碼中通過ini_set
進行調整
ini_set("session.save_handler", "redis"); ini_set("session.save_path", "tcp://127.0.0.1:6379”);
如果需要使用redis進行存儲,需要session中的Registered save handlers支持redis
上述內容就是如何在PHP中使用cookie實現跨域session共享,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。