「Race Condition」とは何かと疑問に思っている場合は、システムの欠陥ですが、タイミングに大きく依存しています。詳細については、こちらのウィキを参照してください。
したがって、私が持っている条件は、Facebook Connect に関連し、ASP.NET 4.0 Web アプリケーション (フォーム ベース認証 - IIS7) を使用してシングル サインオン サービスを実装することです。
プロセス自体(ログアウトを含む)はうまく機能していますが、.....
100% 正確に機能していないシナリオを次に示します。
- ユーザーが Facebook にログインします。
- ユーザーが私のウェブサイトに移動します。
- ユーザーは自動的にログインされません (ただし、ログインする必要があります)。
- ユーザーがページを更新すると、自動的にログインされます。
ステップ 3 でコードをブレークポイントすると、Facebook の Cookie はまだ存在しません ( HttpContext.Current.Request.Cookies
.
しかし、ページがリロードされると (ステップ 4)、Facebook の Cookie が存在します。
私にとって、それはいくつかの可能性があります:
Facebook が私のアプリケーションに Cookie へのアクセスを許可していないだけなのか (クロスドメイン ハンドシェイクの遅延 - xd_receiver.htm)、クロスドメイン Cookie 自体と ASP の問題なのかはわかりません。 NET ページのライフサイクル。
他の誰かがこの問題に対処しましたか?
これは「万能」ではありませんが、面倒です (そして、ユーザーの観点からはあまり良くありません)。
編集:
わかりました、今何か変なことに気づきました。(Facebook経由で)Facebookにログインし、20秒待ってから私のWebサイトにアクセスすると、まだログインしません。2回目のロード後にのみログインします。タイミングの問題ではないかもしれません-なぜですかCookie を読み取るには 2 回更新する必要がありますか?
混乱を解消するために、Facebook は Cookie を設定し (ユーザーが Facebook にログインしている)、私の Web サイトはこれらの Cookie を読み取ります。
これは、すべてのページ要求で発生します (すべての単一ページにあるユーザー コントロールのロジック)。
protected void Page_PreRender(object sender, EventArgs eventArgs)
{
if (FacebookUser.IsAuthenticated) // static property, checks HttpContext.Request.Cookies
{
// log them into my website
}
}
したがって、最初の更新では、HttpContext.Request.Cookies には何もありません。
2 回目の更新では、それらはそこにあります。
これは、ページ要求ごとに FB.Init がクライアント側で実行されるためだと思います。これは、Cookie を初期化するものです。そのため、(Facebook にログインした後) サーバー側 (Cookie をチェックする場所) で初めて私の Web サイトにアクセスしたとき、この関数はまだ実行されていません。
だから私はここで負け戦を戦っていると思います(クライアント側に設定されているCookieサーバー側にアクセスしようとしています)。
編集2:
これが私の初期化コードです(window.loadで実行):
FB.init('myapikey', 'xd_receiver.htm', null);
私は今、次のようなことをしようとしています:
FB.init('myapikey', 'xd_receiver.htm', null);
FB.getLoginStatus(function(response) {
if (!response.session) {
return false;
}
else {
window.location.reload();
}
});
しかし、JavaScript エラーが発生しています。「FB.getLoginStatus」は関数ではありません。=(
これは、次の JavaScript ライブラリを使用しているためです: http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php/en_US
他の人はこれを使うと言っていますが: http://connect.facebook.net/en_US/all.js
新しい JS API の doco を見ていました。
このスレッドに出くわした他の人への参照として、ここに「古い」JS API のドコがあります: http://developers.facebook.com/docs/reference/oldjavascript/
したがって、FB.Connect.get_status() を使用してこの問題を解決し、ユーザーが認証されている場合はウィンドウをリロードします。
みんなの助けに感謝します。
これは、他の誰かが気にする場合の問題に対する私の「解決策」です。
window.onload = function() {
FB.init('{0}', 'xd_receiver.htm');
FB.ensureInit(function() {
FB.Connect.ifUserConnected(onUserConnected, onUserNotConnected);
});
};
function onUserConnected() {
alert('connected!');
window.location.reload();
}
function onUserNotConnected() {
alert('not connected');
}
もちろん、window.location.reload() を実行する前に、フォーム認証 Cookie を確認する必要があります。そうしないと、ページが更新され続けます。=)