using Microsoft.AspNetCore.WebUtilities;
using System.Security.Cryptography;
namespace UserManager.Cryptography
{
public class UrlToken
{
private const int BYTE_LENGTH = 32;
/// <summary>
/// Generate a fixed length token that can be used in url without endcoding it
/// </summary>
/// <returns></returns>
public static string GenerateToken()
{
// get secure array bytes
byte[] secureArray = GenerateRandomBytes();
// convert in an url safe string
string urlToken = WebEncoders.Base64UrlEncode(secureArray);
return urlToken;
}
/// <summary>
/// Generate a cryptographically secure array of bytes with a fixed length
/// </summary>
/// <returns></returns>
private static byte[] GenerateRandomBytes()
{
using (RNGCryptoServiceProvider provider = new RNGCryptoServiceProvider()) {
byte[] byteArray = new byte[BYTE_LENGTH];
provider.GetBytes(byteArray);
return byteArray;
}
}
}
}
I've created the above class (C#, .Net Core 2.0) to generate a cryptographically secure string token that is URL safe, so it can be used in an URL without the necessity to be encoded.
I will use that token as a GET
parameter (e.g. www.site.com/verify/?token=v3XYPmQ3wD_RtOjH1lMekXloBGcWqlLfomgzIS1mCGA
) in a user manager application where I use the token to verify the user email or to recover a user password.
The above link will be sent as email to the user that has requested the service.
I store the token into a DB table with an associated expiration datetime.
I've seen other implementations on this and other sites but all seem to be unnecessarily complicated. Am I missing something?