我正在为应用程序编写api 任务是在确认电子邮件后重定向到客户端上的配置文件页面。虽然未确认电子邮件,但我无法将访问令牌提供给api。 目前,客户端上存在拐杖:用户名和密码 暂时存储在本地,以便客户可以隐藏登录后(不安全)
该问题如何解决?
我有一个不太好的主意:注册后提供访问令牌,然后对每个请求进行检查-emailConfirmed(bool) 但是-每次都要执行一个额外的请求...
后面的小代码示例:
ApplicationOAuthProvider:
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);
var a = await userManager.FindByIdAsync(context.ClientId);
if (user == null)
{
context.SetError("invalid_grant", "Username or Password is incorrect.");
return;
}
if (!user.EmailConfirmed)
{
context.SetError("invalid_grant", "Email not confirmed.");
return;
}
ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager,
OAuthDefaults.AuthenticationType);
ClaimsIdentity cookiesIdentity = await user.GenerateUserIdentityAsync(userManager,
CookieAuthenticationDefaults.AuthenticationType);
AuthenticationProperties properties = CreateProperties(user.UserName);
AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
context.Validated(ticket);
context.Request.Context.Authentication.SignIn(cookiesIdentity);
}
通过电子邮件发送代码:
[AllowAnonymous]
[HttpPost]
[Route("Users/{userId}/emailConfirmation")]
public async Task<IHttpActionResult> SendConfirmationCode(string userId)
{
if (userId == null)
{
return BadRequest("UserId were not transferred");
}
var user = await UserManager.FindByIdAsync(userId);
if (user == null)
{
return Content(HttpStatusCode.NotFound, "User not found");
}
var code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
var url = $"{clientBaseUrl}confirm_email?userId={user.Id}&code={WebUtility.UrlEncode(code)}";
await MailHelper.SendConfirmationLinkOnEmail(url, user.Email);
return Content(HttpStatusCode.OK, new { Message = "Confirmation code was sent on email" });
}
通过代码确认电子邮件:
[AllowAnonymous]
[HttpPost]
[Route("Users/{userId}/emailConfirmationCode")]
public async Task<IHttpActionResult> ConfirmEmail(string userId, [FromBody]EmailConfirmationDTO input)
{
if (userId == null || input == null)
{
return BadRequest("UserId or code were not transferred");
}
try
{
var isConfirmed = await UserManager.IsEmailConfirmedAsync(userId);
if (isConfirmed)
{
return Content(HttpStatusCode.Forbidden, new { Message = "This user already confirmed email" });
}
var result = await UserManager.ConfirmEmailAsync(userId, input.Code);
if (result.Succeeded)
{
var user = Db.Users.FirstOrDefaultAsync(u => u.Id == userId);
return Content(HttpStatusCode.OK, new { responseObj = user });
}
}
catch (Exception e)
{
// ignored
}
return Content(HttpStatusCode.InternalServerError, new { Message = "Error confirmation." });
}
ConfigureAuth:
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(5),
#if (!DEBUG)
AllowInsecureHttp = false
#else
AllowInsecureHttp = true
#endif
};