0

私のasp.net mvcアプリケーションでは、ユーザーが登録すると、アプリを使用する前に確認のためのリンクをアカウントに送信します。下記のコードスニペットを参照してください。電子メール確認トークンを検証するにはどうすればよいですか?

 var emailActionLink = Url.Action("ValidateAccount", "Register", 
      new { Token = registeredUserViewModel.Id, Username = registeredUserViewModel.Username }, 
      Request.Url.Scheme); 

上記のスニペットは、この方法は、彼らがその上にルート値を持つアクションを呼び出しますクリックしますどのようなアクション問題がある

public ActionResult ValidateAccount(string token, string username) 
    { 
     try 
     { 
      if (!string.IsNullOrEmpty(token) && !string.IsNullOrEmpty(username)) 
      { 
       var user = _userServiceClient.IsUserNameAvailable(username); 
       if (!user.HasValue) throw new NullReferenceException("This account does not exist"); 



       var userContract = user.Value; 
       userContract.EmailVerified = true; 
       if (_userServiceClient.UpdateUser(userContract) == null) throw new Exception("Something has gone wrong"); 
       return View("ValidationCompleted"); 
      } 
      else 
      { 
       ViewBag.RegisteredUser = null; 
      } 
     } 
     catch (Exception exception) 
     { 
      throw; 
     } 

     return View(); 
    } 

検証アカウントですトークンを検証していない場合、誰かがURIのtokenの値を変更するとどうなりますか?これは引き続き、非常にアカウントに渡ります。これを改善するための正しいアプローチは何でしょうか。

この場合、トークンはGUIDであるユーザーのIDですが、コード化されているため、データベースのユーザーのIDとこのエンコードされたトークンを比較する方法はありません。私はこれがアクションリンクでコード化されていると思います。

答えて

1

あなたのIDを使用するのではなく、おそらくテーブルのトークンフィールドを持つほうがよいでしょう。(検証後にクリアできるように、nullが可能です) URLセーフなトークンを生成します(私は特殊文字を使用しない16進文字列を使用します)。次に、検証アクションでデータベース内のそのトークンを探します。あなたのサービスクラスに適切なメソッドを追加し、その後

public class TokenGenerator 
{ 
    public static string GenerateToken(int size = 32) 
    { 
     var crypto = new RNGCryptoServiceProvider(); 
     byte[] rbytes = new byte[size/2]; 
     crypto.GetNonZeroBytes(rbytes); 

     return ToHexString(rbytes, true); 
    } 

    private static string ToHexString(byte[] bytes, bool useLowerCase = false) 
    { 
     var hex = string.Concat(bytes.Select(b => b.ToString(useLowerCase ? "x2" : "X2"))); 

     return hex; 
    } 
} 

:ここ

は、トークン生成の例です明らかに

public YourUserType GetUserForToken(string token, string userName) 
{ 
    return YourDbContext.Users 
     .SingleOrDfault(user => user.Token.Equals(token, StringComparison.OrdinalIgnoreCase) 
      && user.UserName.Equals(userName, StringComparison.OrdinalIgnoreCase)); 
} 

、これはあなたのテーブル構造とデータアクセスの上、いくつかの仮定をしますコード。

+1

私は電子メールに送られたURLに実際にユーザーIDが含まれていることを認識しました。私はまだあなたのアプローチが良いと思う、私はすでにDBのEmailVerificationTokenフィールドを持って、これは私がパスワードをハッシュする方法に似ているので、私はあなたのソリューションに満足していると思う。私はそのようなものを使うようにリファクタリングします –

関連する問題