确认电子邮件后如何授权用户?

时间:2019-05-07 05:22:13

标签: c# authentication asp.net-web-api2

我正在为应用程序编写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
            };

0 个答案:

没有答案