1

This is directly related to how to generate a unique token which expires after 24 hours?

What I am attempting to do is embed the following:

  1. A Page Number (0 through 6)
  2. Current Date/Time Stamp in UTC Format
  3. and A Unique GUID

The code I have so far is this:

private string GenerateToken(Int32 pageNumber)
{
    byte[] currentTimeStamp = BitConverter.GetBytes(DateTime.UtcNow.ToBinary());
    byte[] key = Guid.NewGuid().ToByteArray();
    byte[] newPageNumber = BitConverter.GetBytes(pageNumber);
    string token = Convert.ToBase64String(newPageNumber.Concat(currentTimeStamp).Concat(key).ToArray());
    return token;
}

private tokenClass TokenAuthenticates(string token)
{
    byte[] data = Convert.FromBase64String(token);

    tokenClass _token = new tokenClass()
    {
        PageNumber = 0,
        TokenDateTimeStamp = DateTime.FromBinary(BitConverter.ToInt64(data, 1)),
        TokenKey = new Guid(),
        Validates = (DateTime.FromBinary(BitConverter.ToInt64(data, 1)) < DateTime.UtcNow.AddHours(-2))
    };

    return _token;
}

The page and Guid parameters in the decoder are not yet figured out yet so they are basically dummies.

What do I need to do to make this work?

Community
  • 1
  • 1
John Schultz
  • 672
  • 1
  • 10
  • 29
  • Whats not working? – CodingYoshi Dec 21 '16 at 04:50
  • first... I need to be able to pull the page number from the Base64String and I have no idea how to do that. Also the date is showing like 1594 instead of 2016 for the guid, same as the page number and the validates solely depends on a valid date – John Schultz Dec 21 '16 at 04:53
  • I havent actually... I was trying to adapt the example SO page referenced and unfortunately I have had absolutely NO luck. – John Schultz Dec 21 '16 at 05:29

1 Answers1

3

Generate your token like this:

private static string GenerateToken(Int32 pageNumber)
{
    byte[] currentTimeStamp = BitConverter.GetBytes(DateTime.UtcNow.ToBinary());
    var keyGuid = Guid.NewGuid();
    byte[] key = keyGuid.ToByteArray();
    byte[] newPageNumber = BitConverter.GetBytes(pageNumber);

    // date plus page number plus key
    string token = Convert.ToBase64String(currentTimeStamp.Concat(newPageNumber).Concat(key).ToArray());
    return token;
}

Read the token like this (in your TokenAuthenticates method):

byte[] data = Convert.FromBase64String(token);

// It will take eight bytes starting at index 0
DateTime when = DateTime.FromBinary(BitConverter.ToInt64(data, 0)); 

// 8 first bytes was taken by date so lets skip 8 and then take 4 since page number is an integer and takes 4 bytes
int pageNumber = BitConverter.ToInt32(data.Skip(8).Take(4).ToArray(), 0);

// 8 bytes for date + 4 bytes for page number so we skip 12 and then take 16 for Guid
// Guid can be generated directly from the bytes
Guid key = new Guid(data.Skip(12).Take(16).ToArray());

Here is a way so you do not have to hardcode the numbers or determine the size. Use the sizeof operator to do the determination for you:

int pageNumber = BitConverter.ToInt32(data.Skip(sizeof(long))
                     .Take(sizeof(int)).ToArray(), 0);

// Skip date and pageNumber, the rest is Guid
Guid key = new Guid(data.Skip(sizeof(long) + sizeof(int)).ToArray());

I would call the method AuthenticateToken since it is an action verb and sounds more readable and clear. You can perform your further validation after you have read the token. You may want to consider encrypting the token too.

CodingYoshi
  • 25,467
  • 4
  • 62
  • 64