Como usar o gerenciamento de usuários de identidade com Cordova e OAuth.io?

9

Eu quero fazer um aplicativo de telefone Cordova e um aplicativo da web. Tanto o aplicativo quanto o aplicativo compartilham o mesmo banco de dados.

No aplicativo móvel, as ações do usuário enviam solicitações para um serviço da Web (via https) que grava no banco de dados. No aplicativo para dispositivos móveis, eu uso o link para permitir que o usuário se registre e faça login com vários provedores de autenticação abertos. Tentando fazer o trabalho para o facebook, por enquanto.

Não consigo entender como usar o gerenciamento de usuários de identidade nesse contexto. A maioria dos exemplos que encontro são no contexto de um aplicativo da web em que o usuário clica e chama o controlador de conta. No meu caso, o lib oauth.io chama facebook, retorna um token de acesso, que eu passo para o meu serviço.

O aplicativo cordova passa o accessToken a esse método para o serviço da Web do lado do servidor.

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 

Eu tentei isso:

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

Não funciona porque o objeto usermanagement dentro do controlador de conta é nulo. Há uma sobrecarga do construtor AccountController, mas tenho a sensação de que estou fazendo tudo errado.

Digamos que o lado do servidor receba um token de acesso do Facebook. Como usar o sistema de gerenciamento de usuários OWIN e Identity de lá?

    
por Dave 14.11.2014 в 20:25
fonte

1 resposta

2

Ok.

Como sugerido por um amigo, substituí os controladores etc. do modelo original da API da web para os que estão no Projeto de amostra de identidade

Aqui está o método chamado pelo aplicativo móvel, com um jsonp angular

[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 !";
    }
}

aqui está o CreateUserAsync que eu fiz

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;
        }
    }
}

E, quando o aplicativo para dispositivos móveis retornar meu serviço da web, posso verificar se a sessão existe da seguinte forma:

[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" });
}

Sim, está certo. Um se e uma sessão. Assim como eu estava fazendo há 13 anos.

Além disso, ao fazer essa abominação, me deparei com um problema pendente no arquivo IdentityConfig.cs.

Aparentemente, o problema é conhecido pela Microsoft e eu acho que é provavelmente corrigido na versão 3 do Owin? Mas eu não sabia sobre a versão 3 naquele momento, então eu segui o Programa trava durante a inicialização do banco de dados . / p>

Por alguma razão, alguns dos métodos postados em sua solução não existiam para mim. Acabei consertando o código o melhor que pude:

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();

    }

}

Além disso, caso alguém esteja se perguntando como chamar o serviço svc do celular, aqui está o código.

(é um pouco confuso, mas as partes importantes estão lá.) (lembre-se de que estou usando o link )

$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;
});

Problemas

A partir de agora, não estou criando um Login, apenas um usuário é criado.

Além disso, a versão OWIN do projeto é 2.0 e, aparentemente, existe um 3.0.

Para ser honesto, quanto mais eu leio on-line, mais eu sinto que tudo que eu fiz é um grande truque no caminho certo para fazê-lo. Eu simplesmente não consegui descobrir. Isso é incrivelmente enorme, confuso, chaótico e quebrado. Sim, acrescentei uma opinião à minha resposta.

    
por Dave 21.11.2014 / 20:16
fonte