使用WebForms登录后存储用户数据的位置

时间:2013-08-06 16:10:27

标签: c# session cookies login

我正在使用C#中的VS2010开发WebForms Web应用程序。我使用自定义登录方法来验证用户,我不想使用Membership框架。用户登录后,我想将用户数据存储为userId,用户名,姓氏,电子邮件等,这样我就可以在所有页面的用户会话期间访问它们。

我该怎么做?我不想将用户数据存储在UserData的{​​{1}}属性中。

我找到了这种方法:Should I store user data in session or use a custom profile provider?,但我不明白如何实现它。

我有一些问题:
1)在我的登录页面中,在db上检查凭据后对用户进行身份验证我使用:FormsAuthentication.SetAuthCookie(txtUserName.Value,true);现在在我的默认页面中我有:
FormsAuthenticationTicket ticket =((FormsIdentity)(User.Identity))。票证;我使用ticket.Name来显示用户名。这是对的吗?你为什么要使用Thread.CurrentPrincipal.Identity.Name谈论线程? 2)我在global.asax文件中有这个代码来读取用户角色并将它们存储到HttpContext中:

void Application_AuthenticateRequest(object sender,EventArgs e)     {

FormsAuthenticationTicket

我可以在从global.asax文件而不是login.aspx页面写入时将用户数据存储到会话中吗?

3 个答案:

答案 0 :(得分:5)

为了便于调试,我建议使用Session Facade设计模式described here,它允许您以更有条理的方式使用HttpContext.Current.Session对象存储当前用户的数据。 / p>

例如,会有一个文件(例如SessionFacade.cs)负责处理传递给Session的值;在你的情况下,它可能看起来像:

public static class SessionFacade
{
    public static int UserId
    {
        get {
            if (HttpContext.Current.Session["UserId"] == null)
                HttpContext.Current.Session["UserId"] = 0;
            return (int)HttpContext.Current.Session["UserId"];
        }
        set {
            HttpContext.Current.Session["UserId"] = value;
        }
    }
    // ... and so on for your other variables
}

然后,在代码中的其他位置,一旦检查完凭据,就可以执行...

if (credentialsAreOk) {
    SessionFacade.UserId = /* insert ID here */
    // ...
}

...而不是手动将值分配给Session对象。这可以确保Session中的变量类型正确,并且在调试时更容易跟踪。然后,要从程序中的任何位置获取UserId,它只是SessionFacade.UserId

(是的,该片段来自Eduard的答案;您仍然应该查看答案,因为它提供了关于WebForms如何工作的信息;请记住,在您的代码中手动调用Session对象可能会非常混乱并且Session Facade使该过程更加清洁)

答案 1 :(得分:3)

如果通过“在VS#中使用VS2010的Web应用程序”,你谈论的是ASP.NET(MVC或Classic),并且通过“自定义登录方法”,你指的是FormsAuthentication那么你需要的只是做的是在登录时将您以后需要的信息存储到Session对象上。

假设您正在使用ASP.NET Classic,并且您有一个登录页面

enter image description here

有2个用户名和密码输入和一个名为“登录”的提交按钮

enter image description here

在按钮的(服务器端)OnClick事件处理程序中,您应该执行以下操作:

public partial class Login : System.Web.UI.Page {

    protected void Page_Load(object sender, EventArgs e) {

    }

    private bool CheckUserPass(string username, string password) {
        // access DB or some other form of storage service
        return true;
    }

    protected void buttonLogin_Click(object sender, EventArgs e) {

        bool credentialsAreOk = this.CheckUserPass(
            this.textBoxUsername.Text,
            this.textBoxPassword.Text
        );

        if (credentialsAreOk) {
            this.Session["EMAIL_ADDRESS"] = "SomeEmail@SomeEmailProvider.com";
            this.Session["OTHER_INFORMATION_KEY"] = "Some other stuff which you have access to during the login process";
            this.Session["TIME_OF_LOGIN"] = DateTime.UtcNow;

            FormsAuthentication.RedirectFromLoginPage(this.textBoxUsername.Text, createPersistentCookie: false);
        }

    }

}    

因此,简而言之,如果您正在使用FormsAuthentication,那么用户名可以存储在会话中,就像您告诉FormsAuthentication系统当前会话应该从非身份验证转换为身份验证一样:

FormsAuthentication.RedirectFromLoginPage(this.textBoxUsername.Text, createPersistentCookie: false);

而其他信息可以放在Session对象上(就像你将键值对添加到Dictionary中一样):

this.Session["TIME_OF_LOGIN"] = DateTime.UtcNow;

虽然很明显你以后如何访问相同的信息(对于相应的用户):

DateTime whenDidILogin = (DateTime) this.Session["TIME_OF_LOGIN"];
// this line of code can be used in any other page
// at any later time - it's like you have a global set of variables
// which exist for each and every distinct session you might have

可能很重要的是,可以通过Thread.CurrentPrincipal静态属性来访问用户名(如果未明确放置在Session对象上,就像其他示例一样):

using System.Threading;

public void SomeWhereInYourApp() {
    bool wasIAuthenticated = Thread.CurrentPrincipal.Identity.IsAuthenticated;
    string whatIsMyUsername = Thread.CurrentPrincipal.Identity.Name;

    // do something with that information
}

答案 2 :(得分:0)

Membership提供程序可帮助您存储数据以及用于身份验证。这样的事情: -

Session["UserName"] = Membership.GetUser().UserName