首页 > 解决方案 > 获取从社交登录提供商返回的流量,以在我的 .net core 2.2 Web 应用程序上创建本地帐户

问题描述

我一直使用家庭烘焙和 3rd 方包的组合来完成社交登录(特别是谷歌、Facebook 和 Twitter)。在我完全控制的情况下,我可以指定返回方法,然后从社交提供者那里获取响应数据,将我想要的字段(姓名、电子邮件地址和第 3 方 ID)映射到我自己的本地模型以创建本地用户帐户然后指定是什么类型的帐户(管理员、普通用户等)。

使用.net core 2.2,一切似乎都发生在幕后,我不知道如何在调用 /me 后返回时捕获流量,例如在 facebook 中。幕后调用返回一个 JSON 响应,然后我的本地应用程序将映射到声明以让我登录。这一切都很好,但我还想捕获该数据并在我自己的数据存储中创建一个本地用户帐户。

我可以看到这一切都发生在提琴手中,所以我知道它仍在工作,我只是不知道如何利用它来提取我在这个阶段需要的东西。在这里以 facebook 为例,我想我可以更改我的 startup.cs 文件中的 facebookOptions.CallbackPath 属性,然后将该回调作为接受的回调添加到 facebook 应用程序中,在与该路径匹配的控制器上连接一个方法,然后从那里获取数据。我可以手动完成剩下的过程,但所做的只是将 .net 核心正在执行的幕后工作移到那个“位置”。

我想我可以在每次用户通过身份验证时点击网站上的页面时进行检查,以查看我是否需要添加或更新他们的本地会话,但这对我来说似乎过于贫民窟。我希望他们一登录就可以在每个会话中执行一次。我将是第一个承认我的身份技能很弱的人,所以也许我在那里遗漏了一些东西?

任何指导或建议将不胜感激。

TIA

标签: c#facebook-graph-apiasp.net-coreasp.net-identityasp.net-core-2.1

解决方案


我想出了一种方法来做到这一点,但我不确定这是否是最好的方法。我创建了一个带有静态方法的辅助类,我在 AddAuthentication() 内部的 Options.Events.OnCreatingTicket 事件中调用该方法启动.cs。

从这里,我可以遍历我的声明列表,将用户保存到我的本地数据存储中,并创建或更新本地用户信息。

如果这不是处理这个问题的最佳方法,我希望有更好的方向。

TIA

            services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme,
                options =>
                {
                    options.LoginPath = new PathString("/account");
                })
            .AddFacebook(facebookOptions =>
                {
                    facebookOptions.AppId = Configuration["Authentication:Facebook:AppId"];
                    facebookOptions.AppSecret = Configuration["Authentication:Facebook:AppSecret"];
                    facebookOptions.CallbackPath = new PathString("/account/facebook");
                    facebookOptions.Events.OnCreatingTicket = ctx =>
                    {
                        ExternalLoginProviderHelper.LoginLocally(ctx.Principal);
                        return Task.CompletedTask;
                    };
                })
            .AddGoogle(options =>
                {
                    options.ClientId = Configuration["Authentication:Google:ClientId"];
                    options.ClientSecret = Configuration["Authentication:Google:ClientSecret"];
                    options.Events.OnCreatingTicket = ctx =>
                    {
                        ExternalLoginProviderHelper.LoginLocally(ctx.Principal);
                        return Task.CompletedTask;
                    };
        });

和我的助手类:

public class ExternalLoginProviderHelper
{
    public static void LoginLocally(ClaimsPrincipal claimsPrincipal)
    {
        foreach(Claim claim in claimsPrincipal.Claims)
        {
            // extract the claim information here (ID, Email address, name (surname, given name) etc)
            // make repository call to save information to the datastore and get a local user ID
        }
        // also set other claims for local user id, user type (admin, regular user) etc.
        ClaimsIdentity claimsIdentity = (ClaimsIdentity)claimsPrincipal.Identity;
        claimsIdentity.AddClaim(new Claim("usertype", "admin")); // this is just an example N/V pair
    }
}

推荐阅读