本文實例講述了php實現多站點共用session實現單點登錄的方法。分享給大家供大家參考,具體如下:
最近閑來無事,總結整理下單點登錄的問題。
單點登錄的基本原理為:客戶端共享sesionid,服務器端共享session信息。通過共同的sessionid在服務器端獲得相同session信息,即可達到單點登錄(即多站點共享用戶信息,一處登錄,處處可用)的目的。
單點登錄分為兩種情況:
一、站點部署在同一個服務器,且使用同一個二級域名
這種情況下,比較好解決。
1、首先解決站點在客戶端sessionid(存在cookie中)的共享問題。使用ini_set()函數即可指定cookie的域,如下: ini_set('session.cookie_domain', '.xxxx.com');
//設置服務器cookie的域,xxxx為公用二級域名
2、其次解決站點在服務端的session信息的共享。因為站點在同一個服務器,所以生成的session文件是可以公用的,可以直接使用sessionid獲取對應的session信息。
二、站點部署在不同的服務器,使用不同域名
這種情況比較復雜,因為站點在不同服務器使用不同域名,在客戶端不能使用ini_set設置cookie的作用域,在服務器端也是各自生成自己的session文件,不能共用,但還是用解決的辦法。
1、首先解決客戶端sessionid同步問題。
假設我們有三個站點,域名分別是aa.com,bb.com,cc.com。我們在aa.com上建立一個共用的登陸入口login.php,三個網站的登陸請求全部跳轉到該頁面。代碼流程如下:
1
2
3
4
5
6
7
|
$back = login( $name , $pwd ); //執行登陸操作,成功就寫入session //如果登錄成功,進行以下操作流程 if ( $back ){ $sessionid = session_id(); $key = encode( $session , $keyword ); //生成安全碼 //輸出一個登陸成功提示頁,并跳轉到請求登陸的站點 } |
在登陸成功html提示頁面中添加如下代碼,利用iframe標簽請求需要同步登陸的站點
aa.com和cc.com站點的set_cookie.php文件如下
1
2
3
4
5
|
//解密$key decode( $key ); //把當前站點的sessionid設置為傳遞的sessionid session_id( $_GET [ 'sessionid' ]); session_start(); |
2、解決三個站點服務器端共享session的問題。
前面已經說過,因為三個站點不在同一個服務器,因此會生成各自的session文件,如果想要共享這些文件,又面臨跨域等一系列問題。所以我們轉化思路,不使用文件保存session信息,而是把session信息保存到數據庫中。這樣,只要獲得session信息的sessionid,任何站點都可以訪問相同的session信息。
我們創建一個mysql_session.php文件,用于存儲session信息到數據庫,代碼如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
$gb_DBname = "test" ; //數據庫名稱 $gb_DBuser = "root" ; //數據庫用戶名稱 $gb_DBpass = "" ; //數據庫密碼 $gb_DBHOSTname = "127.0.0.1" ; //主機的名稱或是IP地址 $SESS_DBH = "" ; //數據庫對象 session_module_name( "User" ); //定義session存儲按用戶定義的方式 $SESS_LIFE =get_cfg_var( "session.gc_maxlifetime" ); //得到session的最大有效期,也可以自定義 function sess_open( $save_path , $session_name ) { global $gb_DBHOSTname , $gb_DBname , $gb_DBuser , $gb_DBpass , $SESS_DBH ; if (! $SESS_DBH =mysql_pconnect( $gb_DBHOSTname , $gb_DBuser , $gb_DBpass )){ echo "MySql Error:" .mysql_error(). "" ; die (); } if (!mysql_select_db( $gb_DBname , $SESS_DBH )){ echo "MySql Error:" .mysql_error(). "" ; die (); } return true; } function sess_close(){ return true; } function sess_read( $key ) { global $SESS_DBH , $SESS_LIFE ; $qry = "select value from db_session where sesskey = '$key' and expiry > " .time(); $qid =mysql_query( $qry , $SESS_DBH ); if (list( $value )=mysql_fetch_row( $qid )){ return $value ; } return false; } //寫入session信息。保存session信息的數據表名為:db_session //除了主鍵自增id,需要的字段如下 //sesskey sessionid //values session值 //expiry session的到期日期 function sess_write( $key , $val ) { global $SESS_DBH , $SESS_LIFE ; $expiry =time()+ $SESS_LIFE ; $value = $val ; $qry = "insert into db_session values('$key',$expiry,'$value')" ; $qid =mysql_query( $qry , $SESS_DBH ); if (! $qid ){ $qry = "update db_session set expiry=$expiry, value='$value' where sesskey='$key' and expiry >" .time(); $qid =mysql_query( $qry , $SESS_DBH ); } return $qid ; } function sess_destroy( $key ) { global $SESS_DBH ; $qry = "delete from db_session where sesskey = '$key'" ; $qid =mysql_query( $qry , $SESS_DBH ); return $qid ; } function sess_gc( $maxlifetime ) { global $SESS_DBH ; $qry = "delete from db_session where expiry < " .time(); $qid =mysql_query( $qry , $SESS_DBH ); return mysql_affected_rows( $SESS_DBH ); } session_set_save_handler( "sess_open" , "sess_close" , "sess_read" , "sess_write" , "sess_destroy" , "sess_gc" ); |
之后在需要使用session的頁面中,在session_start()之前引入該文件,其他的跟平時使用seesion一樣就可以了。你會發現你賦值的session已經被存進了數據庫中。
希望本文所述對大家PHP程序設計有所幫助。
原文鏈接:https://blog.csdn.net/u012830303/article/details/82252708