6

私はあなたが助けてくれることを願っている問題を抱えています。私が「Blammo」という架空の会社で働いていて、「Log」という架空の製品があるとします。誰かがlogfromblammo.comにログインして製品の一部を注文できるシステムをセットアップしようとしています。購入の準備ができたら、checkout.blammo.comにアクセスして注文の支払いを行います。最終的には、Blammoが独自のWebサイトrockfromblammo.comで新しい架空の製品を立ち上げ、そのサイトがcheckout.blammo.comとセッションを共有できるようにして、ユーザーが両方の製品で1つのショッピングカートを持つことができるようにしたいと考えています。ウェブサイト。

当然のことながら、上記の架空のシナリオは私の会社が実際にどのように機能しているかではありませんが、それは私がしなければならないことの公正な例です。既存のユーザーデータベースがあり、任意のサイトの任意のユーザーを認証する方法がありますが、私が持っている目標は、ユーザーが再認証することなく、あるサイトから別のサイトにシームレスに移動できるようにすることです。これにより、ショッピングカートなどのデータをチェックアウトサイトにシームレスに転送することもできます。

私は(簡単に)OpenIDなどのソリューションを見てきましたが、私たちが持っているソリューションを、それほど堅牢ではない既存の認証方法と統合できる必要があります。PHPだけでこれを行う良い方法はありますか?

4

5 に答える 5

8

あなたができることは、セッションを引き継ぐためにサイト間に「クロスオーバー」リンクを作成することです。

最も簡単な方法は、クエリ文字列を介してセッションIDを渡すことです。例えば

http://whateverblammo.com/?sessid=XXYYZZ

誰もがその情報をトラップできると考える前に、Cookieがどのように転送されるかを考えてください。SSLを使用していないと仮定すると、ネットワークを利用する人にとっては大きな違いはありません。

それは安全だという意味ではありません。1つは、ユーザーが誤ってアドレスバーをコピーして貼り付け、セッションがリークする可能性があることです。この露出を制限するために、セッションIDを受け取った後、すぐにページにリダイレクトすることができます。

mcrypt()問題となるのは値の可視性ではないため、セッションIDでの使用はあまり役に立たないことに注意してください。セッションハイジャックは、基になる値を気にせず、URLの再現性だけを気にします。

IDを1回だけ使用できることを確認する必要があります。これは、使用回数を追跡するセッション変数を作成することで実行できます。

$_SESSION['extids'] = array();

$ext = md5(uniqid(mt_rand(), true)); // just a semi random diddy
$_SESSION['extids'][$ext] = 1;

$link = 'http://othersite/?' . http_build_query('sessid' => session_id() . '-' . $ext);

受け取ったとき:

list($sid, $ext) = explode('-', $_GET['sessid']);
session_id($sid);
session_start();
if (isset($_SESSION['extids'][$ext])) {
    // okay, make sure it can't be used again
    unset($_SESSION['extids'][$ext]);
}

前回からセッションが再生成されている可能性があるため、境界を越えるたびにこれらのリンクが必要になります。

于 2012-12-10T18:37:39.900 に答える
4

それは可能ですが、単純なCookieを使用することはできず、簡単ではありません。あなたが求めているのは、シングルサインオン(SSO)ソリューションです。これは、i.google.com、gmail.com、youtube.comなどでログイン情報を共有するGoogleのソリューションに似ています。

私は過去にOpenIDを使用してこれを実装しました。

基本的な考え方は、単一の認証ドメイン(プロバイダー)を持つことです。サイトの1つ(コンシューマー)がユーザーを認証する場合は常に、ユーザーを認証ドメインにリダイレクトします。サインインしていない場合は、必要な詳細情報を使用してログインできます。

(別のターゲットサイトからでも)すでにログインしている場合は、再度ログインする必要はありません。

次に、URLにトークンを追加して、ユーザーをターゲットサイトに送り返します。このトークンは、ユーザーが認証サーバーで認証されていることを確認するために、ターゲットサイトのサーバーによって使用されます。

これは非常に簡単な説明です。これを行うことは難しくありません、それを安全に行うことははるかに難しいです。トークンを安全に生成および認証することの詳細は、難しい部分です。そのため、OpenIDなどの適切に設計されたシステムに基づいて構築することをお勧めします。

于 2012-12-10T18:38:54.153 に答える
3

クロスドメインAjaxでは、クロスドメインリクエストでCookieとそれに続くセッションが失われる場合があります。サイトexample.comからサブドメインs2.example.comにajax呼び出しを行う場合は、PHPのヘッダーでプロパティを使用する必要があります。

header('Access-Control-Allow-Origin: https://example.com');
header('Access-Control-Allow-Credentials: true');

そしてJSであなたは追加しようとしています

xhrFields: { withCredentials: true }

そうしないと、Cookieが渡されず、サブドメインでセッションを利用できません。

サブドメインへの完全なJSリクエストは、セッションを失うことなく行われます。

$.ajax({
    url: "https://s2.example.com/api.php?foo=1&bar=2",
    xhrFields: { withCredentials: true },
    success:function(e){
        jsn=$.parseJSON(e);
        if(jsn.status=="success") { 
                alert('OK!');
        } else {
                alert('Error!');
        }
    }
}) 
于 2017-12-27T14:02:19.653 に答える
1

次のようにセッションCookieドメインを設定する必要があります。

session_set_cookie_params($lifetime,$path,'.site.com')

TLDこれは、サイトが(トップレベルドメイン)を含む同じドメイン名にある場合にのみ機能します。

詳細については、こちらをご覧ください

site1.netまたは、fromからのように、ドメイン間でセッションにアクセスしようとしている場合site2.com、これは実行できません。

于 2012-12-10T18:21:19.513 に答える
0

サイトが機能するためにJavascriptに依存しても問題がない場合は、おそらく次のようなことを行うことができます。

blammo.comでセッションがあり、rockblammo.comからアクセスしたいとします。<script>からロードできるrockblammo.comページでblammo.com/get-session.js、これは(サーバー側から)セッションIDを返します。それが戻ったら<script>、ページに新しいタグを挿入しますrockblammo.com/set-session.js?sessionId=XXX。ここで、XXXはblammo.comから取得したセッションIDです。これで、rockblammo.comのサーバー側で、セッションCookieが更新され、このセッションIDに設定されます。今後、2つのページは同じセッションIDを共有し、バックエンドの同じセッションストアにアクセスできると仮定すると、同期されます。

たとえば、からの出力は次のblammo.com/get-session.jsようになります。

var sessionId = "XXX";
var s = document.createElement("script");
s.src = "/set-session.js?sessionId=" + escape(sessionId);
document.body.appendChild(s);

からの出力はrockblammo.com/set-session.js空白になりますが、次のようなhttpヘッダーが含まれます。

Set-Cookie: sessionId=XXX

Javascriptに依存したくない場合は、2つのサイト間で前後にリダイレクトし、クエリ文字列パラメーター(GET param)でsessionIdを渡すことで同じことができます。

于 2012-12-10T18:46:37.367 に答える