c# – 如何在MVC 4应用程序中进行单用户登录

前端之家收集整理的这篇文章主要介绍了c# – 如何在MVC 4应用程序中进行单用户登录前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在实施一个应用程序,其中使用该应用程序的公司中的每台机器都有一个机制.我正在尝试实现一个用户策略,如果用户处于“Mechanic”角色 – 用户名为Machine1,并且已登录该机器,则只有一个用户可以使用Machine1用户名同时登录公司.
如果其他人尝试使用相同的用户名登录,则应阻止该用户名并告知已登录用户.当会话超时到期时,我应该注销登录用户并释放要使用的登录名.当用户自己注销时也会发生同样的情况.我正在尝试在asp.net MVC 4应用程序上构建它.

我曾想过在数据库中使用SessionId,UserId和IsLoggedIn布尔值.但在这种情况下,我需要更改MVC应用程序中会话超时的登录标志以写入数据库,如果许多用户登录,这似乎有点过分.

实施会是什么样的?我应该使用哪些方法属性来处理数据库中的会话管理?

FYI

我已经制作了自己的方法,我检查用户是否已登录,这里是:

public static bool ValidateUser(string username,string password,string companyName)
{
    int? companyId = myRepository.GetCompanyId(companyName);

    int? userId = companyId == 0 ? null : myRepository.GetUserId(username,companyId);

    if (userId.HasValue && userId.Value != 0)
    {
        var userKey = Security.GenerateUserKey(username,companyName);
        return WebSecurity.Login(userKey,password);
    }
    else
    {
        return false;
    }
}

在这个方法中,我可以检查会话ID是否与数据库中的相同.

解决方法

此问题的关键问题是知道用户何时注销以允许下一个用户使用相同的名称.我不知道在Web应用程序中执行此操作的确切方法,但这里有一种方法可以通过控制用户登录的持续时间来了解用户何时注销.为了测试这个,我将超时设置为1分钟,这样我就可以快速测试具有相同用户名的不同用户之间的连接.您可以通过web.config控制它.
<forms loginUrl="~/Account/Login" timeout="1" slidingExpiration="false" />

请注意,我将slidingExpiration设置为false以准确知道它们何时将被注销.如果使用滑动过期,则无法预测实际发生注销的时间,因为您无法指望用户实际注销.

为了跟踪当前登录用户,我使用了MemoryCache并使用其过期策略自动跟踪我的时间.这是我写的一个简单的帮助类来管理它.

public class UserManager
{
    public static bool IsLoggedIn(string username)
    {
        ObjectCache cache = MemoryCache.Default;
        return !string.IsNullOrEmpty(cache[username] as string);

    }

    public static void SetToLoggedIn(string username)
    {
        ObjectCache cache = MemoryCache.Default;
        CacheItemPolicy policy = new CacheItemPolicy();
        //Expires after 1 minute.
        policy.AbsoluteExpiration = new DateTimeOffset(DateTime.Now.AddMinutes(1));
        cache.Set(username,username,policy);

    }
}

请注意,我使用AbsoluteExpiration并将超时设置为我为表单身份验证设置的相同长度.这将从写入时起1分钟内从缓存中清除对象.这样我就可以检查缓存中是否存在对象,以确定用户登录的分配时间是否已经过去.我使用用户名作为缓存对象的密钥,因为我们在任何时候检查具有该用户名的一个用户是否在系统中.

现在我们只需将登录操作更改为这样.

[HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public ActionResult Login(LoginModel model,string returnUrl)
    {
        if (ModelState.IsValid )
        {
            if (UserManager.IsLoggedIn(model.UserName))
            {
                ModelState.AddModelError("","A user with that user name is already logged in.");
                return View(model);
            }
            if (WebSecurity.Login(model.UserName,model.Password,persistCookie: model.RememberMe))
            {
                UserManager.SetToLoggedIn(model.UserName);
                return RedirectToLocal(returnUrl);
            }
        }

        // If we got this far,something Failed,redisplay form
        ModelState.AddModelError("","The user name or password provided is incorrect.");
        return View(model);
    }

我使用SimpleMembership在MVC 4应用程序上测试了它,它可以工作.我用这种方法可以看到的唯一缺点是你需要绝对超时而不是滑动.获得正确的超时设置对于减少用户以特定时间间隔注销的挫败感并最大限度地减少其他用户必须等待登录的时间至关重要.

猜你在找的C#相关文章