如何使用Cordova和OAuth.io的身份用户管理?

Dav*_*ave 9 c# facebook oauth cordova asp.net-identity

我想制作一个Cordova手机应用程序和一个Web应用程序.应用程序和应用程序共享同一个数据库.

在移动应用程序上,用户操作将请求发送到写入数据库的Web服务(通过https).在移动应用程序上,我使用https://oauth.io让用户注册并使用多个开放的身份验证提供程序登录.现在尝试让它适用于Facebook.

我无法想象如何在该上下文中使用Identity用户管理.我发现的大多数示例都是在用户点击的Web应用程序的上下文中,它调用了帐户控制器.在我的例子中,oauth.io lib调用facebook,返回一个访问令牌,我将其传递给我的服务.

cordova应用程序将accessToken传递给我的服务器端Web服务.

var client = new FacebookClient(accessToken);

if (client != null)
{
    dynamic fbresult = client.Get("me");

    if (fbresult["id"] != null)
    {

        var fbid = fbresult["id"].ToString();

        and where do we go from now ?
        how do I insert a new user 
Run Code Online (Sandbox Code Playgroud)

我试过这个:

var user = new ApplicationUser() { UserName = fbresult["id"] };
Backend.Controllers.AccountController ac = new Controllers.AccountController();
ac.UserManager.CreateAsync(user);
Run Code Online (Sandbox Code Playgroud)

不起作用,因为帐户控制器内的用户管理对象为空.AccountController构造函数有一个重载,但我有一种感觉,我正在以错误的方式做这整件事.

假设服务器端收到facebook访问令牌.如何使用OWIN和Identity用户管理系统?

Dav*_*ave 2

好的。

根据朋友的建议,我将原始 Web api 模板中的控制器等替换身份示例项目中的控制器等

这是移动应用程序调用的方法,带有角度 jsonp

[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json)]
public string StartSession(string accessToken)
{
    if (!HttpContext.Current.Request.IsAuthenticated)
    {
        var client = new FacebookClient(accessToken);

        if (client != null)
        {
            dynamic fbresult = client.Get("me");

            if (fbresult["id"] != null)
            {
                string fbid = fbresult["id"].ToString();

                ApplicationUser user = null;

                using (var context = new ApplicationDbContext())
                {
                    user = context.Users.FirstOrDefault(u => u.UserName.ToString() == fbid);
                }

                if (user == null)
                {
                    CreateUserAsync(fbid);
                    return "user created. ";
                }
                else
                {
                    HttpContext.Current.Session["user"] = "holy fuck";                                                  
                    return "user logged in. ";
                }
            }
        }
        return "ok";
    }
    else
    {
        return "already auth !";
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我制作的 CreateUserAsync

public async System.Threading.Tasks.Task<bool> CreateUserAsync(string fbid)
{

    using (var context = new ApplicationDbContext())
    {

        var newUser = new ApplicationUser() { UserName = fbid, Email = "xxx@gmail.com" }; 
        var userManager = new ApplicationUserManager(new UserStore<ApplicationUser>(context));

        try
        {
            var result = await userManager.CreateAsync(newUser, "Admin@123456");
            var test   = await context.SaveChangesAsync();                    

            return result.Succeeded;                   
        }
        catch (Exception ex)
        {

            throw ex;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,当移动应用程序回调我的网络服务时,我可以检查会话是否存在,如下所示:

[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json)]
public async Task<string> TestLogin(int id, string callback)
{

    if (HttpContext.Current.Session["user"] != null)
    {
        return new JavaScriptSerializer().Serialize(new word() { Name = "woot" });        
    }
    else
        return new JavaScriptSerializer().Serialize(new word() { Name = "not logged" });
}
Run Code Online (Sandbox Code Playgroud)

是的,没错。一个 if 和一个会话。就像我13年前所做的那样。

另外,在执行此令人厌恶的操作时,我偶然发现了 IdentityConfig.cs 文件中的一个悬而未决的问题。

显然,这个问题是微软已知的,我猜它可能在 Owin 版本 3 中得到修复?但当时我不知道版本3,所以我遵循了Programhangs during Database初始化

由于某种原因,他的解决方案中发布的某些方法对我来说并不存在。我最终尽我所能修复了代码:

public static void InitializeIdentityForEF(ApplicationDbContext db)
{
    //ApplicationUserManager userManager = HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>();
    RoleManager<IdentityRole> roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(db));

    const string name = "admin@example.com";
    const string password = "Admin@123456";
    const string roleName = "Admin";

    IdentityRole adminRole = new IdentityRole(roleName);


    //Create Role Admin if it does not exist
    if (!roleManager.RoleExists(roleName))
    {
        roleManager.Create(adminRole);

        PasswordHasher hasher = new PasswordHasher();

        ApplicationUser adminUser = new ApplicationUser { UserName = name, Email = name, PasswordHash = hasher.HashPassword(password), LockoutEnabled = false };
        db.Users.Add(adminUser);

        IdentityUserRole userRole = new IdentityUserRole() { RoleId  = adminRole.Id, UserId = adminUser.Id };
        adminUser.Roles.Add(userRole);

        var x = db.SaveChanges();

    }

}
Run Code Online (Sandbox Code Playgroud)

另外,以防万一有人想知道如何从移动设备调用 svc 服务,这里是代码。

(有点乱,但重要的部分都在那里。)(请记住我正在使用https://oauth.io/

$scope.refresh = function () {

$http.jsonp("https://10.0.100.38:6443/Service1.svc/helloworld?id=1&callback=JSON_CALLBACK").success(function JSON_CALLBACK(result) {

    OAuth.popup('facebook')
   .done(function (oauthResult) {

       oauthResult.me() // standardise lesfield firstname, first-name etc
       .done(function (response) {
           alert("3");


           $http.jsonp("https://10.0.100.38:6443/Service1.svc/StartSession?accessToken=" +oauthResult.access_token + "&callback=JSON_CALLBACK").success(function JSON_CALLBACK(result) {
               alert("done " +result); // StartSession serverside success ");

    }).error(function (data, status, headers, config) {
                   alert("icierror2" +data + " " +status + " " +headers + " " + config);

               $scope.status = status;
               });
       }).fail(function (error) {
           alert("icierror3 " +error);
       });
       })
   .fail(function (error) {
       console.log(error);
});

    alert(result.Name); // result de la svc request over https

    }).error(function (data, status, headers, config) {
        alert("icierror" +data + " " +status + " " + headers + " " +config);

    $scope.status = status;
});
Run Code Online (Sandbox Code Playgroud)

问题

截至目前,我没有创建登录名,只创建了一个用户。

另外,该项目的 OWIN 版本是 2.0,并且显然存在 3.0。

老实说,我在网上阅读的内容越多,我就越觉得我所做的一切都是围绕正确方法进行的大修改。我就是想不通。这是一个非常巨大、令人困惑、混乱和破碎的东西。是的,我在我的答案中添加了意见。