ASP.NET成员资格将用户 - 用户ID激活为查询字符串

时间:2014-11-13 06:41:22

标签: c# asp.net membership-provider

我有ASP会员默认提供商的网站。我想通过电子邮件激活新用户,并链接到“激活”页面。在电子邮件html我添加了链接到“激活”页面与查询字符串的用户ID,以激活它。 这样做是否安全? 它接收敏感数据,但我可以找到任何alternative.code“激活”页面:

protected void Page_Load(object sender, EventArgs e)
{
    //request for signed user UserId
    Guid newUserId = new Guid(Request.QueryString["UserId"]);
    //get signed user
    MembershipUser newUser = Membership.GetUser(newUserId);
    //activate signed user
    newUser.IsApproved = true;
    Membership.UpdateUser(newUser);
}

在用户使用电子邮件链接激活帐户后,我在激活页面中有以下代码。我得到“对象引用没有设置为对象的实例”错误的行“newUser.IsApproved = true;”。 我检查userId字符串,它获取用户Id字符串,字符串不为空。为什么我会收到此错误?

    //request for signed user UserId
    Guid activationCode = new Guid(Request.QueryString["ActivationCode"]);
    string userId = "";

    string ConnectionString = ConfigurationManager.AppSettings["myConnectionString"];
    try
    {
        using (SqlConnection sqlConnection = new SqlConnection(ConnectionString))
        {
            SqlCommand sqlCommand = new SqlCommand("SELECT user_id FROM ActivationCode WHERE activation_code LIKE '%" + activationCode + "%'", sqlConnection);
            sqlConnection.Open();
            SqlDataReader userIdRdr;
            userIdRdr = sqlCommand.ExecuteReader();
            while (userIdRdr.Read())
            {
                userId = userIdRdr["user_id"].ToString();
            }
            sqlConnection.Close();

            MembershipUser newUser = Membership.GetUser(userId);
            //activate signed user
            newUser.IsApproved = true;
            Membership.UpdateUser(newUser);
        }
    }

2 个答案:

答案 0 :(得分:1)

您可能遇到的问题是,有人可以通过简单地生成激活链接来激活他的帐户,例如:

  1. 用户注册和给定的ID,ID可能在网页(或网址/ cookie)的某处可见
  2. 用户知道他的身份生成"激活"链路
  3. 在未实际验证电子邮件的情况下激活了用户帐户。
  4. 我宁愿生成一个唯一的字符串/ guid,并将其与用户ID一起存储在数据库中,并使用它来生成激活链接。所以流程将是这样的:

    1. 用户注册和给定的id,生成并存储在db
    2. 中的唯一激活guid / string(令牌)
    3. 使用激活令牌生成的用户链接
    4. 用户点击从用户ID
    5. 的数据库中检索到的链接,激活令牌
    6. 已激活用户帐户,已删除用户令牌。
    7. 激活页面可能需要登录。

答案 1 :(得分:0)

试试这个

private void SendActivationEmail(string userId)
{
 string connectionString = ConfigurationManager.ConnectionStrings["connectionString"].ConnectionString;
 string activationCode = Guid.NewGuid().ToString();
 try
 {
   using (SqlConnection sqlConnection = new SqlConnection(connectionString))
   {
     SqlCommand sqlCommand = new SqlCommand("spInsertActivationCode", sqlConnection);
     sqlCommand.CommandType = CommandType.StoredProcedure;
     sqlCommand.Parameters.AddWithValue("@UserId", userId);
     sqlCommand.Parameters.AddWithValue("@ActivationCode", activationCode);
     sqlConnection.Open();
     sqlCommand.ExecuteNonQuery();
     sqlConnection.Close();

     //Afer successfull inserion of Activation Code You can send mail 

     using (MailMessage message = new MailMessage("sender@gmail.com", txtEmail.Text))
     {
       message.Subject = "Account Activation";
       string body = "Hello " + txtUsername.Text.Trim() + ",";
       body += "<br /><br />Please click the following link to activate your account";
       body += "<br /><a href = '" + Request.Url.AbsoluteUri.Replace("User.aspx", "User_Activation.aspx?ActivationCode=" + activationCode) + "'>Click here to activate your account.</a>";
       body += "<br /><br />Thanks";
       message.Body = body;
       message.IsBodyHtml = true;
       SmtpClient smtpClient = new SmtpClient();
       smtpClient.Host = "smtp.gmail.com";
       smtpClient.EnableSsl = true;
       NetworkCredential networkCredentials = new NetworkCredential("sender@gmail.com", "<password>");
       smtpClient.UseDefaultCredentials = false;
       smtpClient.Credentials = networkCredentials;
       smtpClient.Port = 587;
       smtpClient.Send(message);
     }
   }
 }
 catch (Exception ex)
 {
   //error
 }
}

------------存储过程-------

CREATE PROCEDURE spInsertActivationCode
@UserId VARCHAR(30),
@ActivationCode VARCHAR(200)

AS
BEGIN
  INSERT INTO tblActivationCode VALUES(@UserId,@ActivationCode)
END

希望这会对你有所帮助。