首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过OAuth从Mastodon API获得用户电子邮件

通过OAuth从Mastodon API获得用户电子邮件
EN

Stack Overflow用户
提问于 2022-11-11 22:39:17
回答 1查看 68关注 0票数 0

是否可以通过Mastodon Api获得用户电子邮件?我正在通过Mastodon添加OAuth身份验证,但似乎只使用"/api/v1/accounts/verify_credentials"端点来获得"id""display_name"。我没有看到一个属性返回电子邮件,所以目前只是使用"acct"参数。我同时使用"read:accounts""admin:read:accounts"作用域。这是用于NetCore应用程序的。

代码语言:javascript
复制
            builder.Services.AddAuthentication()
                .AddMicrosoftAccount("Microsoft", "Microsoft", microsoftOptions =>
                {
                    microsoftOptions.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
                    microsoftOptions.ClientId = _appSettings.Authentication.Microsoft.ClientId;
                    microsoftOptions.ClientSecret = _appSettings.Authentication.Microsoft.ClientSecret;
                })
                .AddGoogle("Google", "Google", googleOptions =>
                {
                    googleOptions.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
                    googleOptions.ClientId = _appSettings.Authentication.Google.ClientId;
                    googleOptions.ClientSecret = _appSettings.Authentication.Google.ClientSecret;
                })
                .AddGitHub("GitHub", "GitHub", githubOptions =>
                {
                    githubOptions.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
                    githubOptions.ClientId = _appSettings.Authentication.GitHub.ClientId;
                    githubOptions.ClientSecret = _appSettings.Authentication.GitHub.ClientSecret;
                })
                .AddOAuth("Fosstodon", "Fosstodon", fosstodonOptions =>
                 {
                     fosstodonOptions.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;

                     fosstodonOptions.ClientId = _appSettings.Authentication.Fosstodon.ClientId;
                     fosstodonOptions.ClientSecret = _appSettings.Authentication.Fosstodon.ClientSecret;
                     fosstodonOptions.CallbackPath = new PathString("/signin-fosstodon");

                     fosstodonOptions.AuthorizationEndpoint = _appSettings.Authentication.Fosstodon.AuthorizationEndpoint;
                     fosstodonOptions.TokenEndpoint = _appSettings.Authentication.Fosstodon.TokenEndpoint;
                     fosstodonOptions.UserInformationEndpoint = _appSettings.Authentication.Fosstodon.UserInformationEndpoint;

                     fosstodonOptions.SaveTokens = true;
                     fosstodonOptions.Scope.Add("read:accounts");
                     fosstodonOptions.Scope.Add("admin:read:accounts");

                     fosstodonOptions.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "id");
                     fosstodonOptions.ClaimActions.MapJsonKey(ClaimTypes.Name, "name");
                     fosstodonOptions.ClaimActions.MapJsonKey(ClaimTypes.Email, "email");

                     fosstodonOptions.Events = new OAuthEvents
                     {
                         OnCreatingTicket = async context =>
                         {
                             var request = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint);
                             request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                             request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken);

                             var response = await context.Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, context.HttpContext.RequestAborted);
                             response.EnsureSuccessStatusCode();

                             var user = JObject.Parse(await response.Content.ReadAsStringAsync());

                             var identifier = user.Value<string>("id")?.Clean();
                             if (!string.IsNullOrEmpty(identifier))
                             {
                                 context.Identity?.AddClaim(new Claim(
                                     ClaimTypes.NameIdentifier, identifier,
                                     ClaimValueTypes.String, context.Options.ClaimsIssuer));
                             }

                             var userName = user.Value<string>("display_name")?.Clean();
                             if (!string.IsNullOrEmpty(userName))
                             {
                                 context.Identity?.AddClaim(new Claim(
                                     ClaimTypes.Name, userName,
                                     ClaimValueTypes.String, context.Options.ClaimsIssuer));
                             }

                             var userEmail = user.Value<string>("acct")?.Clean();
                             if (!string.IsNullOrEmpty(userEmail))
                             {
                                 context.Identity?.AddClaim(new Claim(
                                     ClaimTypes.Email, userEmail,
                                     ClaimValueTypes.String, context.Options.ClaimsIssuer));
                             }
                         }
                     };
                 });

真正想知道他们是否是一个端点,将返回当前用户电子邮件地址。我看过乳齿象文献,但没有看到和指点这一点。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-11-13 02:58:17

发现无法通过Mastodon Api获得用户电子邮件。相反,决定在汉德尔这种情况下,在注册过程中进行申请认证流程。基本检查用户是否存在与给定的电子邮件。如果是,则删除自动提供程序用户,并向现有用户添加外部提供程序信息。稍后将提交核实电子邮件,以电子邮件地址提供,以避免某人窃取用户帐户通过注册。

代码语言:javascript
复制
        /// <summary>
        /// Handle postback from new registration
        /// </summary>
        /// <returns>IActionResult</returns>
        [AllowAnonymous]
        [HttpPost("Registration/New")]
        [HttpPost("Registration/New/{id?}")]
        [ValidateAntiForgeryToken]
        public virtual async Task<IActionResult> New([Bind(RegistrationViewModel.BindProperties)] RegistrationViewModel model, [FromForm(Name = "Button")] string button)
        {
            // Check if cancled
            if (button.Clean() != "submit")
                return RedirectToAction("Index", "Home");

            // Check email is valid
            if (!model.Email.Clean().IsValidEmail())
                ModelState.AddModelError(nameof(model.Email), _sharedLocalizer["ErrorMessage.Invalid"]);

            if (ModelState.IsValid)
            {
                // setup results
                IdentityResult identityResult = new IdentityResult();

                // Check for existing user
                ApplicationUser user = await _userManager.FindByEmailAsync(model.Email.Clean());
                if (user != null)
                {
                    if (user.Id != model.Id.Clean())
                    {
                        ApplicationUser removeUser = await _userManager.FindByIdAsync(model.Id.Clean());
                        if (removeUser != null)
                        {
                            identityResult = await _userManager.DeleteAsync(removeUser);
                            if (!identityResult.Succeeded) throw new Exception(identityResult.Errors.First().Description);
                        }
                    }
                }
                else
                {
                    user = await _userManager.FindByIdAsync(model.Id.Clean());
                    if (user == null)
                        throw new KeyNotFoundException($"[Key]: {nameof(model.Id)} [Value]: {model.Id}");
                }

                user.DisplayName = model.DisplayName.Clean();
                user.UserName = model.Email.Clean();
                user.NormalizedUserName = model.Email.Clean();
                user.Email = model.Email.Clean();
                user.NormalizedEmail = model.Email.Clean();

                identityResult = await _userManager.UpdateAsync(user);
                if (!identityResult.Succeeded) throw new Exception(identityResult.Errors.First().Description);

                if (!string.IsNullOrEmpty(model.ProviderUserId.Clean()))
                {
                    var userLogins = await _userManager.GetLoginsAsync(user);
                    UserLoginInfo? userLogin = userLogins
                        .Where(x => x.LoginProvider == model.Provider.Clean())
                        .Where(x => x.ProviderKey == model.ProviderUserId.Clean())
                        .FirstOrDefault();

                    if (userLogin == null)
                    {
                        identityResult = await _userManager.AddLoginAsync(user, new UserLoginInfo(model.Provider.Clean(), model.ProviderUserId.Clean(), model.Provider.Clean()));
                        if (!identityResult.Succeeded) throw new Exception(identityResult.Errors.First().Description);
                    }
                }
            }

            return View(model);
        }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74408850

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档