PHP-аутентификация с несколькими доменами и поддоменами - PullRequest
9 голосов
/ 04 ноября 2010

У меня есть один основной домен: main.com, субдомены: test1.main.com, test2.main.com и другие домены one.com, two.com.

Теперь это сделано так:

ini_set("session.cookie_domain", ".main.com");

$domain = 'main.com';

login.php

$user = $db->query("SELECT id, login FROM users WHERE email=? AND password=?", 
array($email, $password), "rowassoc");

if($user)
{
  $_SESSION['user_id'] = $user['id'];
  $_SESSION['user_name'] = $user['login'];

  $time = 100000; 

  setcookie('email', $email, time() + $time, "/", "." . $domain);
  setcookie('password', $password, time() + $time, "/", "." . $domain);

  header('Location: http://' . $user['login'] . "." . $domain);
  exit;
}

добавлено на каждой странице:

if(!isset($_SESSION['user_id']))
{
  if(isset($_COOKIE['email']) && isset($_COOKIE['password']))
  {
    $email = $_COOKIE['email'];
    $password = $_COOKIE['password'];

    $user = $db->query("SELECT id, login FROM users WHERE email=? AND password=?",
    array($email, $password), "rowassoc");

    if($user)
    {
      $_SESSION['user_id'] = $user['id'];
      $_SESSION['user_name'] = $user['login'];
    }
  }
}
else
{
  $user = $db->query("SELECT id, login FROM users WHERE id=?", 
  array($_SESSION['user_id']), "rowassoc");


  if(!$user)
  {
    setcookie('email', '', time() , "/", "." . $domain);
    setcookie('password', '', time() , "/", "." . $domain);
    unset($_SESSION['user_id']);

    session_destroy();
    setcookie("PHPSESSID","",time(), "/", "." . $domain);
  }
  else
  {
    $_SESSION['user_id'] = $user['id'];
    $_SESSION['user_name'] = $user['login'];
  }
}

logout.php

if(isset($_SESSION['user_id']))
{
  setcookie('email', '', time() , "/", "." . $domain);
  setcookie('password', '', time() , "/", "." . $domain);
  unset($_SESSION['user_id']);
  unset($_SESSION['user_name']);

  session_destroy();
  setcookie("PHPSESSID","",time(), "/", "." . $domain);

  header('Location: /main');
  exit;
}

Но работает только на домене main.com и его поддоменах test1.main.com, test2.main.com.

Мне нужно как-то сохранить сеанс и на других доменах one.com, two.com.

Как лучше сделать безопасную аутентификацию, если есть решения, я действительно запутался, расскажите, пожалуйста, с примером.

Ответы [ 3 ]

10 голосов
/ 04 ноября 2010

Насколько я знаю, пересечение сеансов между поддоменами - это хорошо, но оно не переносится на целый новый домен.Для этого вам нужен какой-то метод централизованных данных или API.

Метод базы данных: вам потребуется создать удаленный доступ к данным MySQL, чтобы domain2.com мог обращаться к базе данных на domain1.com.Когда выполняется вход в систему, в базу данных mysql должен быть помещен не только новый сеанс, но и уникальный маркер входа (со сроком действия).Теперь для каждой ссылки, которая идет с domain1.com на domain2.com, вы должны добавить переменную $ _GET, которая содержит случайно сгенерированный идентификатор сеанса (подойдет хэш md5).domain2.com, после получения посетителя, возьмет переменную $ _GET, пропустит ее через базу данных MySQL, чтобы найти токен для входа, и, если есть совпадение, рассмотрим, что пользователь вошел в систему (и, возможно, вставит $ _COOKIE какхорошо хранить данные для входа).Это сделает вход в систему переносимым между двумя совершенно разными доменами.

Метод API : вам необходимо создать метод API, чтобы домен domain1.com мог ответить на внешний запрос авторизованногодомены для получения токена входа в систему при перенаправлении пользователя.Этот метод также потребует добавления всех ссылок, идущих с domain1.com на domain2.com, с помощью переменной $ _GET для передачи уникального хеша сеанса.Затем после получения посетителя domain2.com выполнит запрос curl () для domain1.com/userapi.php (или как вы называете файл), и переменные должны быть проверены на соответствие содержимому базы данных.

Это лучшее, что я могу объяснить ... записать это в коде - значительная часть работы, поэтому я не могу зафиксировать.Но, судя по вашему коду, у вас очень хорошее понимание PHP, поэтому я уверен, что вы справитесь!

Удачи, приятель.

2 голосов
/ 04 июня 2012

Но если пользователь достигает доменов one.com напрямую, то one.com не может знать, если пользователь вошел в систему по правильному ответу, указанному выше, похоже, что он должен использовать дополнительные js, это jsonP!мы позволяем account.main.com / userLoginStat.php? callback = loginThisDomain , чтобы проверить, был ли у пользователя логин main.com, если это так, функция обратного вызова js loginThisDomain делает что-то с autologinпользователь one.com.

1 голос
/ 04 ноября 2010

Чтобы ваши сеансы проходили через несколько доменов, вам нужно использовать session_set_cookie_params () . При этом вы можете указать свой домен. Например ...

session_set_cookie_params(10000, "/", ".main.com");

Это установит тайм-аут сеанса на 10000 секунд для всех документов в корне сайта и для всех поддоменов main.com.

Вы должны позвонить session_set_cookie_params(), прежде чем сделать session_start().

...