gpt4 book ai didi

c# - 在 MVC 中使用 GenerateEmailConfirmationTokenAsync 外部 Controller 的无效 token

转载 作者:行者123 更新时间:2023-11-30 23:05:37 27 4
gpt4 key购买 nike

我已经坚持了好几天了。

我正在使用 GenerateEmailConfirmationTokenAsync 在 Controller 外部创建 token (它工作正常),但不知何故我的 token 比使用 GenerateEmailConfirmationTokenAsync 在 Controller 内创建的 token 长因此 ConfirmEmail 操作拒绝 token 。 (错误:无效 token )。我已经在 web.configHttpUtility.UrlEncode 上尝试了 Machinekey,但我仍然卡住了。

如何解决Controller ConfirmEmail上的Invalid Token错误?

这是我的代码:

RegisterUser( Controller 外部)

public async Task RegisterUserAsync()
{
var store = new UserStore<ApplicationUser>(db);
var UserManager = new ApplicationUserManager(store);

var query = from c in db.Customer
where !(from o in db.Users
select o.customer_pk)
.Contains(c.customer_pk)
select c;
var model = query.ToList();

if (query != null)
{
foreach (var item in model)
{
var user = new ApplicationUser { UserName = item.email, Email = item.email, customerId = item.customerId};
var result = await UserManager.CreateAsync(user);
if (result.Succeeded)
{
string callbackUrl = await SendEmailConfirmationTokenAsync(user.Id);
SmtpClient client = new SmtpClient();
MailMessage message = new MailMessage
{
IsBodyHtml = true
};
message.Subject = "Confirm Email";
message.To.Add(item.email1);
message.Body = "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>";

client.SendAsync(message, "userToken");

//Assign Role User Here
await UserManager.AddToRoleAsync(user.Id, "Client");
}
}
}

}

SendEmailConfirmation 方法( Controller 外部)

public async Task<string> SendEmailConfirmationTokenAsync(string userID)
{
var store = new UserStore<ApplicationUser>(db);
var UserManager = new ApplicationUserManager(store);
var url = new UrlHelper();
var provider = new DpapiDataProtectionProvider("MyApp");
UserManager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(
provider.Create("EmailConfirmation"));
string code = await UserManager.GenerateEmailConfirmationTokenAsync(userID);
string encodedCode = HttpUtility.UrlEncode(code);

string callbackUrl = "http://localhost/Accounts/ConfirmEmail?userId=" + userID + "&code=" + encodedCode;
return callbackUrl;
}

数据库在哪里

ApplicationdDbContext db = new ApplicationdDbContext();

ConfirmEmail 在身份 Controller (帐户 Controller )中 - 我创建了帐户而不是帐户 Controller ,但它工作正常。

//
// GET: /Account/ConfirmEmail
[AllowAnonymous]
public async Task<ActionResult> ConfirmEmail(string userId, string code)
{
if (userId == null || code == null)
{
return View("Error");
}

var confirmed = await UserManager.IsEmailConfirmedAsync(userId);
if (confirmed)
{
return RedirectToLocal(userId);
}
var result = await UserManager.ConfirmEmailAsync(userId, code); //Here I get the error (Token Invlaid, despite the token and userId being displayed)
if (result.Succeeded)
{
ViewBag.userId = userId;
ViewBag.code = code;
}

return View(result.Succeeded ? "ConfirmEmail" : "Error");
}
[HttpPost]
[ValidateAntiForgeryToken]
[AllowAnonymous]
public async Task<ActionResult> ConfirmEmail(SetPasswordViewModel model, string userId, string code)
{
if (userId == null || code == null)
{
return View("Error");
}

if (!ModelState.IsValid)
{
return View(model);
}

var result = await UserManager.AddPasswordAsync(userId, model.NewPassword);
if (result.Succeeded)
{
var user = await UserManager.FindByIdAsync(userId);
if (user != null)
{
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
}

return RedirectToLocal(userId);
}

ViewBag.userId = userId;
ViewBag.code = code;

AddErrors(result);

return View(model);
}

我已经在这段代码中工作了几个小时,但直到现在我还无法解决它。感谢您的任何意见或解决方案。采用这种方法的原因是我必须使用任务调度程序(我使用的是 fluentscheduler,它运行良好)。

最佳答案

您的问题出在这一行:

var provider = new DpapiDataProtectionProvider("MyApp");
UserManager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(
provider.Create("EmailConfirmation"));

DpapiDataProtectionProvider 这里与 Identity 在 IIS 下运行时使用的不同。据我所知,它使用 IIS 网站的内部名称而不是 "MyApp"。它还通过委托(delegate)和作为单例注册它来做一些神奇的事情。

您可以尝试保存对数据保护提供程序的静态引用,并在您的调度程序代码中使用它。在 Startup.Auth.cs 类中执行此操作:

public partial class Startup
{
internal static IDataProtectionProvider DataProtectionProvider { get; private set; }

public void ConfigureAuth(IAppBuilder app)
{
DataProtectionProvider = app.GetDataProtectionProvider();
// other stuff.
}
}

然后在您的 UserManager 中访问该引用,如下所示:

public class UserManager : UserManager<ApplicationUser>
{
public UserManager() : base(new UserStore<ApplicationUser>(new MyDbContext()))
{
var dataProtectionProvider = Startup.DataProtectionProvider;
this.UserTokenProvider =
new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));

// do other configuration
}
}

但是我不熟悉 FluentScheduler 的细节,如果它在单独的 AppDomain 中启动进程,它可能不允许您访问这个静态变量。但请尝试一下,看看它是如何工作的。

关于c# - 在 MVC 中使用 GenerateEmailConfirmationTokenAsync 外部 Controller 的无效 token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48720170/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com