7

私たちのウェブサイトでは、複数のドメインでセッションを共有できるようにしたいと考えています。これらのWebサイトはすべて同じサーバー上にありますが、一部のWebサイトは異なるIPアドレスを持っています。

私が見つけた可能な解決策は、セッションIDを自分で設定することでした。

<?php
session_id($someUniqueHash);
?>

そして、md5('test')のようなハッシュを作成すると、これは機能します。同じサーバー上の他のドメインで、セッションが再開されます。

問題はIDの生成です。インターネット上でマイクロタイムなどの解決策をいくつか見かけますが、そのアプローチを使用すると、他のドメイン/PHPページのセッションIDを予測できません。

誰かアイデアがありますか?それとも、これを実装するべきではありませんか?複数のドメインでセッションを共有する他のオプションはありますか?(サブドメインではありません!)

4

5 に答える 5

5

OAuthタイプのフローを使用してこのシステムを実現しましたが、コンシューマーをユーザーに置き換えました。

したがって、各ドメインは、独自のセッションで認証されたAccess_Tokenを持ちます。次に、そのAccess_Tokenを使用して、APIからユーザーに関する情報を取得します。

また、 session_set_save_handlerを使用してセッションの問題を解決し、データベーステーブルにセッションを保存しました...このテーブルにもAccess_Tokenが含まれるため、DBクエリでセッションを簡単に見つけることができます。

これがアイデアに役立つことを願っています。

于 2012-10-16T00:22:31.120 に答える
0

うーん、これは難しいものです。

誰もが知っているように、PHPはユーザーがサイトに戻ってきたときにsession_idsを理解するためにCookieを使用し、クロスドメインCookieの方法はありません:クロスドメインCookie (編集:ありますが、方法は複雑です)。

ドメインが異なっていても、サイトがこれを実装しているのを見たことがないのは、おそらくこれが理由です。

あるドメインからのページ上のリンクを介して、$_GETまたは$_POSTを介してセッションIDを次のドメインに渡すことができます。ユーザーが他のサイトに直接アクセスした場合、これは機能しません。

私が思いつくことができる唯一の部分的(信頼できない)方法は、DBにユーザーコンピューターの記録を保持し、それを使用して、どのセッションに接続されているかを理解することです。したがって、コンピュータのIPアドレスとその他の詳細を格納し、それをセッションに戻します。

個人のコンピューターのIPおよびその他の詳細は、他のドメインにログインします。

于 2012-06-22T11:41:16.833 に答える
0

多分これはあなたのためのオプションではありませんが、あなたはこれを試すことができます。

メインサイトでは、通常どおりセッションIDを生成し、セッションを別のドメインに永続化するために、URLにセッションIDを含む画像タグを含めることができます。それに応じて、他のドメインはCookieを設定するため、訪問者がそこに来たときに、セッションIDがすでに認識されています。

少し賢い解決策を感じますが、他のドメインがあまり多くない場合は機能するはずです:)サードパーティのCookieは、ブラウザで個別に無効にすることができます。

ところで、セッションの採用(クエリパラメータを介してIDを受け入れ、Cookieを設定する)はデリケートなものであり、保護する必要があります。つまり、Cookieを設定する前にセッションがすでに存在している必要があります。

于 2012-06-22T11:59:26.233 に答える
0

各サイトを個別に構成します。

<?php

$cfgsession['file'] = "../sessions_global.txt";
$cfgsession['keepalive'] = 7200;

?>

複数のサイトでセッションを共有するには、同じサイトを使用するようにします$cfgsession['file']。あるサイトからのセッションを別のドメインへのリクエストに含め(おそらくジャックが推奨するように)、別のブラウザなどでリクエストを行っているのを見つけられない限り(セッションハイジャックを禁止するために何かをしてください)、 $_GETでセッションを指定します。例えば:

include ("../session.php");
if (isset($_COOKIE['session'])) session_begin($_COOKIE['session'], $_SERVER['HTTP_USER_AGENT'] . "+" . $_SERVER['HTTP_ACCEPT_CHARSET'], $_SERVER['REMOTE_ADDR']);
else session_begin("", $_SERVER['HTTP_USER_AGENT'] . "+" . $_SERVER['HTTP_ACCEPT_CHARSET'], $_SERVER['REMOTE_ADDR']);
setcookie("session", session_identity(), 0);

そして、あなた自身のsession_関数をロールするだけです:

<?php

function session_begin($mysession = "", $key = "", $client = "") {
  global $cfgsession;
  if (!preg_match("/^[a-z0-9]{32}$/i", $mysession)) $mysession = md5(microtime());
  $error = false;
  $client = trim($client);
  $key = trim($key);
  $cfgsession['returning'] = false;
  if ($chandle = @tmpfile()) {
    if ($shandle = @fopen($cfgsession['file'], "rb")) {
      flock($shandle, LOCK_SH);
      fputs($chandle, $mysession . " " . time() . " $" . $client . " $" . $key . "\n");
      while (!feof($shandle)) {
        $sline = explode(" ", trim(fgets($shandle)), 4);
        if ($sline[1] >= (time() - $cfgsession['keepalive'])) {
          if (($sline[0] == $mysession) && ($sline[3] == "$" . $key)) {
            $cfgsession['client'] = substr($sline[2], 1);
            $cfgsession['returning'] = true;
          } elseif (count($sline) > 2) fputs($chandle, implode(" ", $sline) . "\n");
        }
      }
      fclose($shandle);
      fseek($chandle, 0);
      if ($shandle = @fopen($cfgsession['file'], "cb")) {
        if (flock($shandle, LOCK_EX)) {
          ftruncate($shandle, 0);
          $cfgsession['count'] = 0;
          while (!feof($chandle)) {
            $cline = trim(fgets($chandle));
            fputs($shandle, $cline . "\n");
            $cfgsession['count']++;
          }
        } else $error = true;
        fclose($shandle);
      } else $error = true;
    } else $error = true;
    fclose($chandle);
  } else $error = true;
  if (($cfgsession['returning'] == false) && ($mysession == $cfgsession['session'])) {
    $cfgsession['returning'] = true;
    $mysession = md5(microtime());
  }
  $cfgsession['session'] = $mysession;

  if ($error) return -1;
  else return 0;
}

function session_count() {
  global $cfgsession;
  return $cfgsession['count'];
}

function session_client() {
  global $cfgsession;
  return $cfgsession['client'];
}

function session_id() {
  global $cfgsession;
  return $cfgsession['session'];
}

function session_index() {
  global $cfgsession;
  $index_return = array();
  if ($uhandle = @fopen($cfgsession['file'], "rb")) {
    flock($uhandle, LOCK_SH);
    while (!feof($uhandle)) {
      $uline = explode(" ", trim(fgets($uhandle)), 4);
      foreach ($uline as &$value) {
        if ($value[0] == "$") $value = substr($value, 1);
      }
      if (count($uline) >= 2) $index_return[] = $uline;
    }
    fclose($uhandle);
  }
  return $index_return;
}

function session_returning() {
  global $cfgsession;
  return $cfgsession['returning'];
}

?>
于 2012-06-23T20:20:40.413 に答える
0

これらがログインセッションである場合は、SAML標準を実装するソリューションなどのシングルサインオン(SSO)ソリューションの使用を検討してください。

于 2018-05-22T15:18:05.653 に答える