回答:
という訳だ
Cookieベースのセッション状態を使用する場合、ASP.NETは、Sessionオブジェクトが使用されるまで、セッションデータ用のストレージを割り当てません。その結果、セッションオブジェクトがアクセスされるまで、ページ要求ごとに新しいセッションIDが生成されます。アプリケーションでセッション全体に静的セッションIDが必要な場合は、アプリケーションのGlobal.asaxファイルにSession_Startメソッドを実装し、データをSessionオブジェクトに格納してセッションIDを修正するか、またはコードの別の部分でコードを使用できます。 Sessionオブジェクトにデータを明示的に格納するアプリケーション。
http://msdn.microsoft.com/en-us/library/system.web.sessionstate.httpsessionstate.sessionid.aspx
したがって、基本的には、バックエンドでセッションオブジェクトにアクセスしない限り、リクエストごとに新しいsessionIdが生成されます
編集
このコードは、Global.asaxファイルに追加する必要があります。エントリがSessionオブジェクトに追加されるため、セッションが期限切れになるまで修正できます。
protected void Session_Start(Object sender, EventArgs e)
{
Session["init"] = 0;
}
someid
セッションを割り当てると、同じままになります。この回答は4年以上前のものであることを考慮に入れてください。これに関して変更があったかどうかはわかりません。
Cladudioによって示されているようにSessionオブジェクトが初期化されている場合でも、これが発生する可能性のある別の、より陰湿な理由があります。
Web.configで、<httpCookies>
設定されているrequireSSL="true"
が実際にはHTTPSを使用していないエントリがある場合、特定のリクエストに対して、セッションCookieは送信されません(または返されない可能性があります。リクエストごとに新しいセッションが発生することになります。
私はこれを困難な方法で見つけ、ソースコントロールのいくつかのコミット間を行ったり来たりして、特定の変更によってアプリケーションが壊れていることがわかるまで、数時間を費やしていました。
私の問題は、これをweb.configに設定したことです
<httpCookies httpOnlyCookies="true" requireSSL="true" />
これは、非SSL(デフォルト)でデバッグする場合、認証Cookieがサーバーに返されないことを意味します。これは、サーバーがすべてのリクエストに対して新しい認証Cookieを(新しいセッションで)クライアントに送信することを意味します。
修正は、web.configでrequiresslをfalseに、web.release.configでtrueに設定するか、デバッグ中にSSLをオンにすることです。
Nevilleの回答を使用して(web.configでrequireSSL = trueを削除)、 Joel Ethertonのコードをわずかに変更します。これは、ユーザーとページに応じて、SSLモードと非SSLモードの両方で実行されるサイトを処理するコードです(Iコードに戻り、SSLでまだテストしていませんが、動作することを期待しています-後でビジー状態になり、これに戻ることができないため、ここに示します。
if (HttpContext.Current.Response.Cookies.Count > 0)
{
foreach (string s in HttpContext.Current.Response.Cookies.AllKeys)
{
if (s == FormsAuthentication.FormsCookieName || s.ToLower() == "asp.net_sessionid")
{
HttpContext.Current.Response.Cookies[s].Secure = HttpContext.Current.Request.IsSecureConnection;
}
}
}
Session_OnStartが定義されている場合やセッションが初期化されている場合でも、SessionIDがリクエスト間で変化するもう1つの可能性は、URLホスト名に無効な文字(アンダースコアなど)が含まれていることです。これはIE固有である(検証されていない)と思いますが、URLがの場合、http://server_name/app
IEはすべてのCookieをブロックし、リクエスト間でセッション情報にアクセスできなくなります。
実際、各リクエストはサーバー上で個別のセッションを起動するため、ページに複数の画像、スクリプトタグなどが含まれている場合、それらのGETリクエストのそれぞれがサーバー上で異なるセッションになります。
私の場合、これは私の開発環境とテスト環境で多く発生していました。上記の解決策をすべて試した後、すべてのセッションCookieを削除することでこの問題を解決できることがわかりました。Web開発者向け拡張機能を使用すると、これを非常に簡単に実行できます。私は主にテストと開発にFirefoxを使用していますが、これはChromeでのテスト中にも起こりました。この修正はChromeでも機能しました。
私はまだ本番環境でこれを行う必要がなく、ログインできないという報告を受けていません。これも、セッションCookieを安全にした後でのみ発生したようです。彼らが安全でないとき、それは過去に決して起こりませんでした。
私の場合は、外部アプリケーションのゲートウェイからリダイレクトした後にセッションを変更していたためです。そのため、そのページのURLでローカルホストの代わりにIPを使用していたため、実際にはセッションが異なる別のWebサイトと見なされていました。
要約すれば
IIS Expressの代わりにIISでホストされているアプリケーションをデバッグし、マシンhttp:// Ipとhttp:// localhostをさまざまなページに混在させる場合は、さらに注意を払います
私の問題は、Microsoft MediaRoom IPTVアプリケーションに関するものでした。MPF MRMLアプリケーションはCookieをサポートしていないことがわかりました。web.configでcookielessセッションを使用するように変更すると、問題が解決しました
<sessionState cookieless="true" />
これに関する本当に古い記事があります: Cookieless ASP.NET
私は.NET Core 2.1を使用していますが、問題はCoreに関するものではないことを十分に認識しています。それでもインターネットが不足していて、Googleが私をここに連れてきたので、誰かを数時間救うことを望んでいます。
Startup.cs
services.AddCors(o => o.AddPolicy("AllowAll", builder =>
{
builder
.WithOrigins("http://localhost:3000") // important
.AllowCredentials() // important
.AllowAnyMethod()
.AllowAnyHeader(); // obviously just for testing
}));
client.js
const resp = await fetch("https://localhost:5001/api/user", {
method: 'POST',
credentials: 'include', // important
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
Controllers/LoginController.cs
namespace WebServer.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class UserController : ControllerBase
{
[HttpPost]
public IEnumerable<string> Post([FromBody]LoginForm lf)
{
string prevUsername = HttpContext.Session.GetString("username");
Console.WriteLine("Previous username: " + prevUsername);
HttpContext.Session.SetString("username", lf.username);
return new string[] { lf.username, lf.password };
}
}
}
セッションの書き込みと読み取りは機能しますが、ブラウザにCookieが渡されないようです。少なくとも "Set-Cookie"ヘッダーはどこにも見つかりませんでした。
これは、.NET 4.7.2以降、私にとっては変わりました。これは、セッションCookieのSameSiteプロパティが原因でした。詳細については、こちらをご覧ください:https : //devblogs.microsoft.com/aspnet/upcoming-samesite-cookie-changes-in-asp-net-and-asp-net-core/
デフォルト値は「緩い」に変更され、物事が壊れ始めました。「なし」に変更したところ、問題なく動作しました。
非常に短いセッションタイムアウトがないことを確認してください。また、Cookieベースのセッションを使用している場合は、セッションを受け入れていることを確認してください。
FireFox webDeveloperToolbarは、アプリケーションに設定されたCookieを確認できるため、このような場合に役立ちます。
セッションIDのリセットには多くの原因が考えられます。ただし、上記のいずれも私の問題とは関係ありません。そのため、今後の参考のために説明します。
私の場合、各リクエストで作成された新しいセッションが無限のリダイレクトループを引き起こしました。リダイレクトアクションはOnActionExecutingイベントで発生します。
また、クライアント側でサイトをキャッシュしないようにするために、(Response.ClearHeadersメソッドを使用してOnActionExecutingイベントでも)すべてのhttpヘッダーをクリアしています。ただし、この方法では、ユーザーのセッションに関する情報を含むすべてのヘッダーが消去され、結果として一時記憶域(後でプログラムで使用していたもの)のすべてのデータが消去されます。そのため、Session_Startイベントで新しいセッションを設定しても効果がありませんでした。
私の問題を解決するために、リダイレクトが発生したときにヘッダーを削除しないようにしました。
それが誰かを助けることを願っています。
私はこの問題に別の方法で遭遇しました。[SessionState(SessionStateBehavior.ReadOnly)]
アプリの起動時に元のセッションで値を設定したにもかかわらず、この属性を持つコントローラーは別のセッションから読み取っていました。私は_layout.cshtmlを介してセッション値を追加していました(おそらく最善のアイデアではないでしょうか?)
属性を削除したときに元のセッション(およびSessionId)がそのまま残るため、これは明らかにReadOnlyが問題の原因でした。クラウディオ/マイクロソフトのソリューションを使用してそれを修正しました。