2016-08-05 69 views
7

這是一個非常類似的問題 aspnet identity invalid token on confirmation email 但這些解決方案無效,因爲我使用的是包含ASP.NET Core Identity的新ASP.NET Core 1.0。確認電子郵件上的ASP.NET Core Identity無效令牌

我的情況如下:

  1. 在後端(ASP.NET核心)我發送密碼重置電子郵件帶有鏈接的功能。爲了生成該鏈接,我必須使用Identity生成一個代碼。像這樣的東西。

    public async Task SendPasswordResetEmailAsync(string email) 
    { 
        //_userManager is an instance of UserManager<User> 
        var userEntity = await _userManager.FindByNameAsync(email); 
        var tokenGenerated = await _userManager.GeneratePasswordResetTokenAsync(userEntity); 
        var link = Url.Action("MyAction", "MyController", new { email = email, code = tokenGenerated }, protocol: HttpContext.Request.Scheme); 
        //this is my service that sends an email to the user containing the generated password reset link 
        await _emailService.SendPasswordResetEmailAsync(userEntity , link); 
    } 
    

    ,這將產生一個鏈接到電子郵件:

    http://myapp:8080/passwordreset?code=CfDJ8JBnWaVj6h1PtqlmlJaH57r9TRA5j7Ij1BVyeBUpqX+5Cq1msu9zgkuI32Iz9x/5uE1B9fKFp4tZFFy6lBTseDFTHSJxwtGu+jHX5cajptUBiVqIChiwoTODh7ei4+MOkX7rdNVBMhG4jOZWqqtZ5J30gXr/JmltbYxqOp4JLs8V05BeKDbbVO/Fsq5+jebokKkR5HEJU+mQ5MLvNURsJKRBbI3qIllj1RByXt9mufGRE3wmQf2fgKBkAL6VsNgB8w==

  2. 然後我AngularJs應用將呈現視圖與表單輸入並確認新密碼,並會放一帶有新密碼的JSON對象以及從URL中的查詢參數獲取的代碼。

  3. 最後我的後端會得到PUT請求,抓取代碼和使用Identity這樣驗證它:

    [HttpPut] 
    [AllowAnonymous] 
    [Route("api/password/{email}")] 
    public async Task<IActionResult> SendPasswordEmailResetRequestAsync(string email, [FromBody] PasswordReset passwordReset) 
    { 
        //some irrelevant validatoins here 
        await _myIdentityWrapperService.ResetPasswordAsync(email, passwordReset.Password, passwordReset.Code); 
        return Ok(); 
    } 
    

的問題是身份與

響應無效標記

錯誤。我已經發現的問題是,碼不匹配和上述代碼將在PUT請求如下被接收回到JSON對象:

CfDJ8JBnWaVj6h1PtqlmlJaH57r9TRA5j7Ij1BVyeBUpqX 5Cq1msu9zgkuI32Iz9x/5uE1B9fKFp4tZFFy6lBTseDFTHSJxwtGu jHX5cajptUBiVqIChiwoTODh7ei4 MOkX7rdNVBMhG4jOZWqqtZ5J30gXr/JmltbYxqOp4JLs8V05BeKDbbVO/Fsq5 jebokKkR5HEJU mQ5MLvNURsJKRBbI3qIllj1RByXt9mufGRE3wmQf2fgKBkAL6VsNgB8w== 

注意,在那裏有+符號現在有空格符號,顯然這會導致Identity認爲令牌是不同的。 由於某種原因,Angular正在以不同的編碼方式解碼URL查詢參數。

如何解決這個問題?

回答

8

這個答案https://stackoverflow.com/a/31297879/2948212指出我在正確的方向。但正如我所說的,它是一個不同的版本,現在它是一個稍微不同的解決方案。

答案仍然相同:以base 64 url​​中的標記進行編碼,然後以base 64 url​​進行解碼。這樣,Angular和ASP.NET Core都會檢索到相同的代碼。

我需要安裝其他依賴於Microsoft.AspNetCore.WebUtilities;

現在的代碼將是這樣的:

public async Task SendPasswordResetEmailAsync(string email) 
{ 
    //_userManager is an instance of UserManager<User> 
    var userEntity = await _userManager.FindByNameAsync(email); 
    var tokenGenerated = await _userManager.GeneratePasswordResetTokenAsync(userEntity); 
    byte[] tokenGeneratedBytes = Encoding.UTF8.GetBytes(tokenGenerated); 
    var codeEncoded = WebEncoders.Base64UrlEncode(tokenGeneratedBytes); 
    var link = Url.Action("MyAction", "MyController", new { email = email, code = codeEncoded }, protocol: HttpContext.Request.Scheme); 
    //this is my service that sends an email to the user containing the generated password reset link 
    await _emailService.SendPasswordResetEmailAsync(userEntity , link); 
} 

和PUT請求

[HttpPut] 
[AllowAnonymous] 
[Route("api/password/{email}")] 
public async Task<IActionResult> SendPasswordEmailResetRequestAsync(string email, [FromBody] PasswordReset passwordReset) 
{ 
    //some irrelevant validatoins here 
    await _myIdentityWrapperService.ResetPasswordAsync(email, passwordReset.Password, passwordReset.Code); 
    return Ok(); 
} 

//in MyIdentityWrapperService 
public async Task ResetPasswordAsync(string email, string password, string code) 
{ 
    var userEntity = await _userManager.FindByNameAsync(email); 
    var codeDecodedBytes = WebEncoders.Base64UrlDecode(code); 
    var codeDecoded = Encoding.UTF8.GetString(codeDecodedBytes); 
    await _userManager.ResetPasswordAsync(userEntity, codeDecoded, password); 
} 
期間回接收代碼的時候