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(); 
    } 

유효성 계정입니다 토큰을 verifiying하지 않으면 누군가가 token의 값을 uri에서 변경하면 어떻게됩니까? 이것은 여전히 ​​지나치게 계좌를 통과합니다. 이를 향상시키는 데 올바른 접근 방법은 무엇입니까?

이 경우 토큰은 GUID 인 사용자의 ID이지만 인코딩되어 있으므로 내 데이터베이스의 사용자 ID를이 인코딩 된 토큰과 비교할 방법이 없습니다. 액션 링크에 인코딩 된 것 같습니다.

답변

1

ID를 사용하는 대신 표에 토큰 필드가있는 것이 좋습니다 (유효성 검사 후 해당 테이블을 삭제할 수 있도록 Null 허용). 특수 문자를 사용하지 않는 16 진수 문자열을 사용하는 URL 안전 토큰을 생성 한 다음 유효성 검사 작업에서 해당 토큰을 데이터베이스에서 찾습니다. 서비스 클래스에 적절한 방법을 추가, 그리고

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 필드가 있습니다. 이것은 암호를 해쉬하는 것과 비슷합니다. 그래서 당신의 솔루션에 만족합니다. 나는 리팩토링가가 그런 것을 사용할 것입니다. –