1 つのユーザー名の同時ログインを防止する機能を作成し、次のようにアクションで呼び出します。
int userId = (int)WebSecurity.CurrentUserId;
if ((this.Session.SessionID != dba.getSessionId(userId)) || dba.getSessionId(userId) == null)
{
WebSecurity.Logout();
return RedirectToAction("Index", "Home");
}
ポイントは、ユーザーがログインするたびに、セッションIDをデータベースフィールドに保存することです。したがって、同じユーザー名ですでにログインしているユーザーに同じユーザー名でログインすると、そのデータベース フィールドがこの新しいセッションで上書きされます。DB の sessionID がログインしているユーザーの現在のセッション ID と同じでない場合、そのユーザーはログアウトされます。
コードのこの部分を 1 か所に配置する可能性はありますか、それともアプリケーションのすべてのアクションに配置する必要がありますか?
Global.asaxで試しました:
void Application_BeginRequest(object sender, EventArgs e)
{
if (Session["ID"] != null)
{
int userId = Convert.ToInt32(Session["ID"]);
if ((this.Session.SessionID != db.getSessionId(userId)) || db.getSessionId(userId) == null)
{
WebSecurity.Logout();
}
}
}
しかし、次のようにしようとすると、ここで Session も WebSecurity クラスも使用できません。
void Application_BeginRequest(object sender, EventArgs e)
{
int userId = (int)WebSecurity.CurrentUserId;
if ((this.Session.SessionID != db.getSessionId(userId)) || db.getSessionId(userId) == null)
{
WebSecurity.Logout();
Response.RedirectToRoute("Default");
}
}
null参照例外が発生するためです。
編集
私はこれを使用しました:
void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
{
int userId = (int)WebSecurity.CurrentUserId;
using (var db = new UsersContext())
{
string s = db.getSessionId(userId);
if ((filterContext.HttpContext.Session.SessionID != db.getSessionId(userId)) || db.getSessionId(userId) == null)
{
WebSecurity.Logout();
filterContext.Result = new RedirectResult("/Home/Index");
}
}
}
コンテキストに using ステートメントを使用する必要がありました。そうしないと、db.getSessionId(userId)が古い sessionId を返していました。メソッドは次のとおりです。
public string getSessionId(int userId)
{
string s = "";
var get = this.UserProfiles.Single(x => x.UserId == userId);
s = get.SessionId;
return s;
}
非常に奇妙です。なぜそれが起こったのかを読む必要があります。
1 つのことを除いて、すべて正常に動作します。Jsonを返すコントローラーにJsonResultアクションが1つありますが、イベント(enterイベントのテキストボックス)がPOSTをトリガーできないため(前にログアウトしたためだと思います)、リダイレクトは機能しません。そのJsonアクションに投稿して、コールバックとリダイレクトを受け取ることさえできません。それに関する手がかりはありますか?
success: function (data) {
if (data.messageSaved) {
//data received - OK!
}
else {
// in case data was not received, something went wrong redirect out
window.location.href = urlhome;
}
}
ActionFilterAttribute を使用する前に、コードを使用して POST 内のさまざまなセッションをチェックしました。もちろん、コールバックを作成できるため、データを受信しなかった場合はリダイレクトできます。リダイレクトしません:)