如何生成一个24小时后到期的唯一令牌?

时间:2013-02-01 10:00:48

标签: c# asp.net wcf authentication token

我有一个WCF Web服务,用于检查用户是否有效。

如果用户有效,我想生成一个在24小时后过期的令牌。

public bool authenticateUserManual(string userName, string password,string language,string token)
{
    if (Membership.ValidateUser(userName,password))
    {
        //////////
        string token = ???? 
        //////////

        return true;
    }
    else 
    {
        return false;
    }
}   

4 个答案:

答案 0 :(得分:133)

有两种可能的方法;要么创建一个唯一的值并将其存储在某处以及创建时间,例如在数据库中,要么将创建时间放在令牌中,以便以后可以解码它并查看它何时被创建。

创建唯一标记:

string token = Convert.ToBase64String(Guid.NewGuid().ToByteArray());

创建包含时间戳的唯一标记的基本示例:

byte[] time = BitConverter.GetBytes(DateTime.UtcNow.ToBinary());
byte[] key = Guid.NewGuid().ToByteArray();
string token = Convert.ToBase64String(time.Concat(key).ToArray());

解码令牌以获得创建时间:

byte[] data = Convert.FromBase64String(token);
DateTime when = DateTime.FromBinary(BitConverter.ToInt64(data, 0));
if (when < DateTime.UtcNow.AddHours(-24)) {
  // too old
}

注意:如果您需要带有时间戳的令牌是安全的,则需要对其进行加密。否则,用户可以找出它包含的内容并创建一个假令牌。

答案 1 :(得分:3)

使用Dictionary<string, DateTime>存储带有时间戳的令牌:

static Dictionary<string, DateTime> dic = new Dictionary<string, DateTime>();

每当您创建新令牌时添加带时间戳的令牌:

dic.Add("yourToken", DateTime.Now);

有一个计时器正在运行以删除任何过期的令牌:

 timer = new Timer(1000*60); //assume run in 1 minute
 timer.Elapsed += timer_Elapsed;

 static void timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        var expiredTokens = dic.Where(p => p.Value.AddDays(1) <= DateTime.Now)
                              .Select(p => p.Key);

        foreach (var key in expiredTokens)
            dic.Remove(key);
    }

因此,当您验证令牌时,只需检查令牌中是否存在令牌。

答案 2 :(得分:0)

您需要在创建第一次注册时存储令牌。当您从登录表中检索数据时,您需要将输入的日期与当前日期区分开来,如果超过1天(24小时),则需要显示令牌已过期的消息。

要生成密钥,请参阅here

答案 3 :(得分:0)

这样,令牌最多可以存在24小时。这是生成令牌的代码,该令牌最多可使用24小时。我们使用的这段代码,但我没有编写。

public static string GenerateToken()
{
    int month = DateTime.Now.Month;
    int day = DateTime.Now.Day;
    string token = ((day * 100 + month) * 700 + day * 13).ToString();
    return token;
}