2012-12-10 15 views
6

私はあなたが援助できることを願っています。私が "Blammo"という仮説的な会社で働いていて、 "Log"という仮説的な製品があるとしましょう。私は誰かがlogfromblammo.comにログインして当社の製品の一部を注文できるシステムをセットアップしようとしています。そして、購入準備が整ったら注文を支払うためにcheckout.blammo.comに行きます。最終的に私はBlammoが独自のウェブサイト(rockfromblammo.com)で新しい仮想製品を立ち上げ、そのサイトでcheckout.blammo.comとセッションを共有できるようにして、ユーザーが両方の製品に1つのショッピングカートを持つことができるようにしたいウェブサイトセキュアでフレキシブルなドメイン間セッション

もちろん、上記のシナリオは私の会社が実際に働く方法ではありませんが、私がする必要があることの公正な例です。私たちには既存のユーザーデータベースがあり、どのサイトでもユーザーを認証する方法がありますが、再認証することなくユーザーがあるサイトから別のサイトにシームレスにアクセスできるようにすることが目的です。これにより、ショッピングカートなどのデータをチェックアウトサイトにシームレスに転送することもできます。

私は(簡単に)OpenIDのようなソリューションを見てきましたが、既存の認証方法とは何か解決策を取り入れる必要があります。これは非常に堅牢ではありません。 PHPだけでこれを行う良い方法はありますか?

+0

だから、基本的にあなたのサイトの代わりに 'product.site.com'種類の複数の第二レベルドメイン名を持っていますか? –

+2

あなたの最善の解決策は、Rockfromblammo.comをrockfrom.blammo.comにリダイレクトすることです。このようなセキュリティはセキュリティが大きな問題であり、2つの異なるドメインへのショッピングカートへのアクセスを許可すると、サードパーティのリスクが発生します同じことをする方法を考え出す。 – Blazemonger

+0

@Blazemongerそれは単なるセキュリティ上のリスクではなく、ドメイン間で行うことはできません。クロスサブドメインでしかできません! –

答えて

7

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

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

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

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

これは安全であるとは限りません。ユーザーが誤ってアドレスバーをコピー/ペーストしてセッションを漏洩する可能性があります。このエクスポージャーを制限するには、セッションIDを受け取った後すぐにそのページにリダイレクトすることができます。

セッションIDにmcrypt()を使用すると、問題の値がわからないため、あまり効果がありません。セッションハイジャックは基本的な価値については気にせず、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]); 
} 

をあなたはこれらのリンク境界が交差するたびを必要とし、セッションので、前回から再生されている可能性があります。

1

あなたはそうのようなセッションCookieドメインを設定する必要があります。サイトはTLD(トップレベルドメイン)を含む同じドメイン名である場合にのみ動作します

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

。あなたがアクセスセッションにしようと見ている場合

site2.comからsite1.netから、その後、これを行うことができないのように、ドメインを渡り、

また詳細はhereを参照してください。

3

とすることができますが、単純なクッキーではできません。それは簡単ではありません。あなたが後にしているのは、i.google.com、gmail.com、youtube.comなどのGoogleの共有ログインと同様のシングルサインオン(SSO)ソリューションです。

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

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

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

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

これは非常に簡単な説明です。これを行うことは難しくありません。が安全です。トークンの生成と認証の詳細は安全です。だから私は、OpenIDのようなうまく設計されたシステムを構築することを提案しています。

0

それが機能するためにはJavaScriptに依存しているためにあなたのサイトのためにOKなら、あなたはおそらく次のような何かができる:

あなたはblammo.com上でセッションを持っていて、rockblammo.comからアクセスしてみたいと思います。あなたは<script>blammo.com/get-session.jsからロードすることができますrockblammo.comページで、これは(サーバー側から)セッションIDを返します。返されたら、新しいタグをrockblammo.com/set-session.js?sessionId=XXXを指すページに挿入します。ここで、XXXはblammo.comから取得したセッションIDです。今、rockblammo.comのサーバー側でセッションクッキーが更新され、このセッション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つのサイト間を行き来し、sessionIdをクエリ文字列パラメータ(GET param)に渡すことで、おそらく同じことをするでしょう。

0

クロスドメインAjaxでは、クロスドメイン要求に対してCookieとそれに続くセッションが失われることがあります。

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

とJSであなたが行く:場合は、あなたは、PHPのためのヘッダーのプロパティを使用する必要がありますサブドメインs2.example.comにあなたサイトexample.comからAJAX呼び出しを行うことになります追加する

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!'); 
     } 
    } 
}) 
関連する問題