asp.net 使用 application 限制单一登录

原理:用户登录后系统会分配一个与用户唯一对应的sessionid,将当前用户id与其sessionid对应保存在application中,一旦该用户在其他地方重复登录则application中保存的sessionid就会被更新,导致当前session中的sessionid与application中的sessionid不再一致

 

用户登录后保存sessionid在application中

private static void recordlogin(string struid)
{
    httpcontext.current.application.lock();
    httpcontext.current.application["sessionid_" + struid] = httpcontext.current.session.sessionid;
    httpcontext.current.application.unlock();
}

 

判断方法

public static bool checkrepeatlogin(string struid)
{
    object objsessionid = httpcontext.current.application["sessionid_" + struid];
    if (objsessionid == null || objsessionid.tostring() == "") return false;

    return objsessionid.tostring() != httpcontext.current.session.sessionid;
}

 

aspx页面跳转时判断:添加基类 basepage.cs

public class basepage:system.web.ui.page
{
    public userinfo curuser = null;

    protected override void oninitcomplete(eventargs e)
    {
        curuser = cursession.curuser;

        if (curuser == null)
        {
            response.redirect(syshelper.getvirtualpath() + "pagesessionnull.html", true);
        }

        if (loginservice.checkrepeatlogin(curuser.uid))
        {
            response.redirect(syshelper.getvirtualpath() + "pagerepeatlogin.html", true);
        }

        base.oninitcomplete(e);
    }

    protected override void onloadcomplete(eventargs e)
    {
        response.cache.setnostore();
        base.onloadcomplete(e);
    }
}

 

ashx页面请求时判断:添加基类 basehandler.cs

public class basehandler : ihttphandler, irequiressessionstate
{
    public userinfo curuser = null;
    public httpcontext curcontext = null;

    public void processrequest(httpcontext context)
    {
        context.response.contenttype = "application/json";
        context.response.charset = "utf-8";
        context.response.cache.setcacheability(httpcacheability.nocache);

        try
        {
            curuser = cursession.curuser;
            curcontext = context;

            if (curuser == null)
            {
                context.response.write(jsonhelper.getresult(false, "登录超时,请重新登录", new { rcode = -98 }));
            }
            else if (loginservice.checkrepeatlogin(curuser.uid))
            {
                context.response.write(jsonhelper.getresult(false, "您的帐号在其他地方登录,您已经被踢出,请重新登录", new { rcode = -99 }));
            }
            else
            {
                context.response.write(actionmethod());
            }
        }
        catch (exception ex)
        {
            context.response.write(jsonhelper.getresult(ex.message.tostring()));
        }
        finally
        {
            context.response.end();
        }
    }

    public virtual string actionmethod()
    {
        return jsonhelper.getresult();
    }
    public bool isreusable
    {
        get
        {
            return false;
        }
    }
}