그러냐

다른 서버, 다른 도메인간 세션 공유 방법 본문

php

다른 서버, 다른 도메인간 세션 공유 방법

관절분리 2016. 1. 25. 14:23
반응형

[PHP] 다른 서버, 다른 도메인간 세션 공유 방법
 

출처 : www.phpschool.com 의 "TarauS" 님이 올려주신 글입니다.
링크 : http://dev.cbmart.net/session/index.php

요번에 프로젝트를 하나 진행하면서 다른 서버이고 다른 도메인 상에서 운영 중인 두개의 사이트의 로그인 정보를 공유할 일이 있어서 만들어봤습니다.
A 서버와 B서버가 따로 있고 각각의 서버에는 aaa.com 과 bbb.com 이 운영중일때 aaa.com에서 로그인을 하면 세션 정보가 공유되어 다른 도메인인 bbb.com에서도 별도의 로그인 절차 없이 하는 방법을 소개해 드립니다.

기본적인 방법은 여기 스쿨에도 많이 올라와 있던 session_set_save_handler을 이용한 DB로의 세션 정보 저장 방법입니다.


먼저 A서버 및 B서버 둘 중 한곳에 DB서버를 두고 아래와 같은 테이블을 하나 생성해 줍니다.

/* Table Scheme
CREATE TABLE sessions (
session_key char(32) not null,
session_expiry int(11) unsigned not null,
session_value text not null,
PRIMARY KEY (session_key)
);
*/

그런 다음 아래의 소스를 복사하여 session.inc 파일을 만듭니다.
소스 중 설정할 변수도 같이 설정해 줍니다.
DB관련 정보는 위에서 만든 테이블이 위치하는 서버의 정보입니다.
쿠키 도메인은 서버의 도메인입니다.(서브도메인에서도 사용하기 위함)
#### session.inc 파일
<?
header('P3P: CP="NOI CURa ADMa DEVa TAIa OUR DELa BUS IND PHY ONL UNI COM NAV INT DEM PRE"');

# 설정할 변수
$Cfg_DB_Host = "localhost";
$Cfg_DB_User = "db_user";
$Cfg_DB_Pass = "db_pass";
$Cfg_DB_Name = "db_name";
$Cfg_Cookie_Domain ".domain.com";

$SESS_DBH = "";
$SESS_LIFE = get_cfg_var("session.gc_maxlifetime");

function sess_open($save_path, $session_name){
global $SESS_DBH,$Cfg_DB_Host,$Cfg_DB_User,$Cfg_DB_Pass,$Cfg_DB_Name;

$SESS_DBH = mysql_pconnect($Cfg_DB_Host,$Cfg_DB_User,$Cfg_DB_Pass) or die("SQL 서버에 접속할 수 없습니다.");
mysql_select_db($Cfg_DB_Name, $SESS_DBH) or die("SQL 서버에 접속할 수 없습니다.");

return true;
}

function sess_close(){
return true;
}

function sess_read($key){
global $SESS_DBH, $SESS_LIFE;

$qry = "SELECT session_value FROM sessions WHERE session_key = '$key' AND session_expiry > " . time();
$qid = mysql_query($qry, $SESS_DBH);

if (list($value) = mysql_fetch_row($qid)) {
return $value;
}

return false;
}

function sess_write($key, $val){
global $SESS_DBH, $SESS_LIFE;

$expiry = time() + $SESS_LIFE;
$value = addslashes($val);

$qry = "INSERT INTO sessions (session_key,session_expiry,session_value) VALUES ('$key', $expiry, '$value')";
$qid = mysql_query($qry, $SESS_DBH);

if (! $qid) {
$qry = "UPDATE sessions SET session_expiry = $expiry, session_value = '$value' WHERE session_key = '$key' AND session_expiry > " . time();
$qid = mysql_query($qry, $SESS_DBH);
}

return $qid;
}

function sess_destroy($key){
global $SESS_DBH;

$qry = "DELETE FROM sessions WHERE session_key = '$key'";
$qid = mysql_query($qry, $SESS_DBH);

return $qid;
}

function sess_gc($maxlifetime){
global $SESS_DBH;

$qry = "DELETE FROM sessions WHERE session_expiry < " . time();
$qid = mysql_query($qry, $SESS_DBH);

return mysql_affected_rows($SESS_DBH);
}

function set_session_id($SESSID){
if($SESSID) @session_id($SESSID);
}

set_session_id($SESSID);
session_set_save_handler("sess_open", "sess_close", "sess_read", "sess_write", "sess_destroy", "sess_gc");
session_set_cookie_params(0, "/", $Cfg_Cookie_Domain);
ini_set('session.cache_limiter' ,'nocache, must-revalidate-revalidate');
session_start();
?>
###################################################################################

이렇게 만든 파일을 A서버와 B서버에 각각 넣어둡니다.
단, 주의할 점은 A서버에 위의 테이블을 만들고 세션 정보를 저장할 것이면 DB의 사용권한
설정 중 B서버에 대해서도 접근 권한을 열어줘야 합니다.
또한 위의 session.inc 파일에서 설정도 달리 해줘야 합니다.
$Cfg_DB_Host 변수도 A서버에 있는 session.inc 파일에서는 localhost 이겠지만 B서버에서는
A서버의 아이피로 지정을 해야겠지요...
그리고 서브 도메인 사용을 위해 $Cfg_Cookie_Domain 도 A서버에서는".aaa.com"와
B서버에서는 ".bbb.com" 로 설정합니다.

이렇게 설정을 하고 프로그램에서 session.inc 파일을 인클루드만 하면 A서버의 DB서버의
sessions 테이블에 세션 정보가 저장이 될 것입니다.(session_set_save_handler을 이용해서
파일로 저장되는 세션 정보를 DB에 저장하는 것임)

여기까지는 다른 세션 공유방법과 비슷할 것입니다. 이렇게하여 세션정보가 DB 한 곳에
저장이 되는 것을 확인하셨다면 다음 작업을 해주시기 바랍니다.
먼저 각 서버에 아래의 파일을 만듭니다.
#### link.php (혹시나 session.inc 파일의 노출을 막기 위함임)
<?
include("session.inc");
?>

그런 다음 로그인 과정 중에 세션을 설정하는 부분에다가
echo "";
을 추가해 줍니다.
이 부분이 키포인트로 link.php파일로 A서버에서 사용하던 세션키를 로그인 과정중에 B서버로
전송해 주는 것입니다. 이 세션키를 받은 link.php파일에서는 session.inc 파일을 인클루드 했고 $SESSID 가 있으므로 session.inc 파일의 set_session_id() 함수에서 받은 $SESSID로
B서버의 세션키를 설정합니다.
이렇게 되면 A서버와 B서버에서 사용자의 세션키가 같아지기 때문에 sessions 테이블에서
같은 레코드를 읽게 되므로 결론적으로는 로그인정보(세션정보)를 공유하게 되는 것입니다.
반응형

'php' 카테고리의 다른 글

[해결법] Fatal error: Allowed memory size of 8388608  (0) 2016.01.25
strip_tags2()  (0) 2016.01.25
preg_replace() - 빠른 정규식  (0) 2016.01.25
PHP 배열의 활용  (0) 2016.01.25
윈도우즈XP에 Apache, PHP, MySQL 설치하기 (06/07/23 ..  (0) 2016.01.25