Oauth - Fazendo integração Oauth com Facebook

Nesta aula iremos aprender como utilizar o Oauth para autenticação única. Usaremos o Facebook como base para nosso estudo. Mostraremos também o uso do swagger para documentação de API.

assinaturaAssine nossa Comunidade

.Net Core - Integração Oauth com Facebook

Para que possamos fazer a autenticação, na nossa aplicação ou API ou algo que seja utilizado para servir como um proxy temos:

  1. Receber um request HTTP na nossa aplicação(através do Browser ou aplicação mobile, etc);
  2. No nosso sistema, iremos obter o arquivo de configuração de acordo com a empresa ou serviço que estamos querendo fazer a autenticação, no nosso caso é o Facebook;
  3. Enviar um Rest HTTP para o Facebook;
  4. O servidor oauth irá obter os dados que enviamos e fará um redirect para uma tela de login;
  5. Na tela de login, o usuário que está querendo fazer a autenticação, digitará seu usuário e senha;
  6. Após o processo anterior, o sistema redirecionará o usuário para o servidor oauth, que por sua vez, irá redirecionar para a nossa aplicação novamente.

    No caso do Facebook, ele retorna um código para o nosso sistema. Esse código servirá para que possamos pedir outra autorização ao Facebook para liberação do access token.

  7. Precisamos fazer novamente uma chamada para o Facebook , enviando o código que foi retornado anteriormente.

    Enviando esse código para o oauth, ele irá processar os dados e verificar se são válidos.

    Caso esteja válido, ele fará um novo request para a nossa aplicação retornando o access token.

  8. Com o Access token vamos fazer as requisições gets na API, retornando o dado válido.

Agora vamos mostrar um exemplo prático de como fazer a autenticação oauth com o Facebook.

Criando o projeto dotnet API

Vamos criar um novo diretório para construir a nossa aplicação Dotnet API.

      
        mkdir oauth_youtube
        cd oauth_youtube
       
    

Vamos criar um novo projeto dotnet API

      
        dotnet new api
       
    

Criando a HomeController

      
        namespace oauth_youtube.Controllers
        {
            [ApiController]
            [Route("[controller]")]
            public class Home : ControllerBase
            {
              [HttpGet]
              [Route("/")]
              public ActionResult Index()
              {
                  return Redirect("/swagger");
              }
            }
        }
       
    

O método Index irá fazer um redirecionamento para o swagger, que basicamente é a documentação da API.

      
        [HttpGet]
        [Route("/")]
        public ActionResult Index()
        {
            return Redirect("/swagger");
        }
       
    

Para veriicar a configuração do swagger , ir para a pasta Properties e abrir o arquivo launchSettings.json:

      
        "profiles": {
          "IIS Express": {
            "commandName": "IISExpress",
            "launchBrowser": true,
            "launchUrl": "swagger",
            "environmentVariables": {
              "ASPNETCORE_ENVIRONMENT": "Development"
            }
          },
          "oauth_youtube": {
            "commandName": "Project",
            "dotnetRunMessages": "true",
            "launchBrowser": true,
            "launchUrl": "swagger",
            "applicationUrl": "http://localhost:5001;http://localhost:5000",
            "environmentVariables": {
              "ASPNETCORE_ENVIRONMENT": "Development"
            }
          }
        }
       
    

Criaremos uma nova rota para o Facebook oauth

      
        namespace oauth_youtube.Controllers
        {
            [ApiController]
            [Route("[controller]")]
            public class Home : ControllerBase
            {
            
              [HttpGet]
              [Route("facebook-oauth")]
              public ActionResult FacebookOauth()
              {
                  return Redirect("/dsd");
              }
            }
        }
       
    

Vamos inicializar a aplicação que irá redirecionar para o swagger:

      
        dotnet watch run
       
    

Configurando a URL do Facebook no projeto

Vamos criar a pasta Servicos e o arquivo OauthConfig no projeto, então teremos a estrutura:

  • OAUTH_YOUTUBE
    • Services
      • OauthConfig.cs

Vamos instalar o pacote Newtonsoft.Json, para ler o arquivo de configuração appsetting.

      
        dotnet add package Newtonsoft.Json --version 13.0.3
       
    

Na classe Services, teremos toda a configuração que precisamos para que o usuário faça login.

      
        using System;
        using System.IO;
        using Newtonsoft.json.Linq

        namespace oauth_youtube.Services
        {
          public class OauthConfig
          {
              public OauthConfig()
              {
                JToken jAppSettings = JToken.Parse(File.ReadAllText(Path.Combine(Environment.CurrentDirectory, "appsettings.json")));                
                this.ClientId = jAppSettings["oauth"]["client_id"].ToString();
                this.AppSecret = jAppSettings["oauth"]["app_secret"].ToString();
                this.RedirectUri = jAppSettings["oauth"]["redirect_uri"].ToString();
                this.Version = jAppSettings["oauth"]["version"].ToString();
              }

              public string ClientId { get; set;}
              public string AppSecret { get; set;}
              public string RedirectUri { get; set;}
              public string Version { get; set;}
          } 
        }
       
    

No arquivo appsettings.json, teremos as configuações que iremos criar no site do Facebook.

      
        "oauth": {
          "client_id": "***********",
          "app_secret": "*********",
          "redirect_uri": "https://localhost:5001/facebook-oauth",
          "version": "v9.0"
       
    

No método FacebookOauth, vamos instanciar a classe OauthConfig :

      
        namespace oauth_youtube.Controllers
        {
            [ApiController]
            [Route("[controller]")]
            public class Home : ControllerBase
            {
            
              [HttpGet]
              [Route("/facebook-oauth")]
              public ActionResult FacebookOauth()
              {
                  var oauthConfig = new OauthConfig();

                  return Redirect($"https://graph.facebook.com/oauth/authorize?client_id={oauthConfig.ClientId}?redirect_uri={oauthConfig.RedirectUri");
              }
            }
        }
       
    

Configurar a conta do Facebook

Ao fazer login com sua conta da empresa no Facebook, localizar o site developers.facebook.com, para criar o app e configurar as chaves client_id e app_secret.

Também é necessário autorizar as urls. Neste caso, as urls serão:

  • https://localhost:5001
  • https://localhost

Acessar o endpoint facebook-oauth

Vamos acessar o endpoint https://localhost5001/facebook-oauth para obtermos o código que o Facebook irá retornar e assim, faremos o segundo redirect com a autorização da chave que iremos precisar.

Para isso vamos alterar o método FacebookOauth para receber o parâmetro code.

      
        namespace oauth_youtube.Controllers
        {
            [ApiController]
            [Route("[controller]")]
            public class Home : ControllerBase
            {
            
              [HttpGet]
              [Route("/facebook-oauth")]
              public ActionResult FacebookOauth(string code = "")
              {
                  var oauthConfig = new OauthConfig();
                  if(string.IsNullOrEmpty(code)){
                    return Redirect($"https://graph.facebook.com/oauth/authorize?client_id={oauthConfig.ClientId}?redirect_uri={oauthConfig.RedirectUri");
                  }
              }
            }
        }
       
    

Caso o parametro code não seja nulo ou vazio, faremos a requisição Http para que seja enviado o token através do parâmetro code.

Para isso iremos utilizar o HttpWebRequest.

      
        using System.Net;
        using System.;
        using Newtonsoft.json.Linq
        namespace oauth_youtube.Controllers
        {
            [ApiController]
            [Route("[controller]")]
            public class Home : ControllerBase
            {
            
              [HttpGet]
              [Route("/facebook-oauth")]
              public ActionResult FacebookOauth(string code = "")
              {
                  var oauthConfig = new OauthConfig();
                  if(string.IsNullOrEmpty(code)){
                    return Redirect($"https://graph.facebook.com/oauth/authorize?client_id={oauthConfig.ClientId}?redirect_uri={oauthConfig.RedirectUri");
                  }
                  string json = string.Empty;
                  HttpWebRequest request = (HttpWebRequest)webRequest.Create($"https://graph.facebook.com/{oauthConfig.Version}/oauth/access_token?client_id={oauthConfig.ClientId}&redirect_uri={oauthConfig.RedirectUri}&client_secret={oauthConfig.AppSecret}&code={code}");
                  HttpWebRequest response = (HttpWebRequest)request.GetResponse();
                  if(response.StatusCode == HttpStatusCode.OK)
                  {
                    Stream receiveStream = response.GetResponseStream();
                    StreamReader readStream = new StreamReader(receiveStream);
                    json = readStream.ReadToEnd();
                    response.close();
                    readStream.close();
                  }
                  var oauthToken = JsonConvert.DeserializeObject< OauthToken>(json);
                  return Redirect($"https://graph.facebook.com/me?fields=name, gender, birthday, picture.width(320).height(320)&access_token={oauthToken.access_token}");
              }
            }
        }
       
    

Com o retorno do json, vamos inserí-lo dentro de um record.

Criaremos uma nova pasta chamada Records e um arquivo chamado OauthToken.cs para armazenar os campos que são retornados do Facebook

      
        using System;
        using System.IO;
        using Newtonsoft.json.Linq

        namespace oauth_youtube.Records
        {
          public record OauthToken
          {
            public string access_token { get; set;}
            public string token_type { get; set;}
            public string expires_in { get; set;}
          } 
        }
       
    

Oauth - Fazendo integração Oauth com Facebook

Nesta aula iremos aprender como utilizar o Oauth para autenticação única. Usaremos o Facebook como base para nosso estudo. Mostraremos também o uso do swagger para documentação de API.

Próximas Aulas:
assinaturaAssine nossa Comunidade

.Net Core - Integração Oauth com Facebook

Para que possamos fazer a autenticação, na nossa aplicação ou API ou algo que seja utilizado para servir como um proxy temos:

  1. Receber um request HTTP na nossa aplicação(através do Browser ou aplicação mobile, etc);
  2. No nosso sistema, iremos obter o arquivo de configuração de acordo com a empresa ou serviço que estamos querendo fazer a autenticação, no nosso caso é o Facebook;
  3. Enviar um Rest HTTP para o Facebook;
  4. O servidor oauth irá obter os dados que enviamos e fará um redirect para uma tela de login;
  5. Na tela de login, o usuário que está querendo fazer a autenticação, digitará seu usuário e senha;
  6. Após o processo anterior, o sistema redirecionará o usuário para o servidor oauth, que por sua vez, irá redirecionar para a nossa aplicação novamente.

    No caso do Facebook, ele retorna um código para o nosso sistema. Esse código servirá para que possamos pedir outra autorização ao Facebook para liberação do access token.

  7. Precisamos fazer novamente uma chamada para o Facebook , enviando o código que foi retornado anteriormente.

    Enviando esse código para o oauth, ele irá processar os dados e verificar se são válidos.

    Caso esteja válido, ele fará um novo request para a nossa aplicação retornando o access token.

  8. Com o Access token vamos fazer as requisições gets na API, retornando o dado válido.

Agora vamos mostrar um exemplo prático de como fazer a autenticação oauth com o Facebook.

Criando o projeto dotnet API

Vamos criar um novo diretório para construir a nossa aplicação Dotnet API.

      
        mkdir oauth_youtube
        cd oauth_youtube
       
    

Vamos criar um novo projeto dotnet API

      
        dotnet new api
       
    

Criando a HomeController

      
        namespace oauth_youtube.Controllers
        {
            [ApiController]
            [Route("[controller]")]
            public class Home : ControllerBase
            {
              [HttpGet]
              [Route("/")]
              public ActionResult Index()
              {
                  return Redirect("/swagger");
              }
            }
        }
       
    

O método Index irá fazer um redirecionamento para o swagger, que basicamente é a documentação da API.

      
        [HttpGet]
        [Route("/")]
        public ActionResult Index()
        {
            return Redirect("/swagger");
        }
       
    

Para veriicar a configuração do swagger , ir para a pasta Properties e abrir o arquivo launchSettings.json:

      
        "profiles": {
          "IIS Express": {
            "commandName": "IISExpress",
            "launchBrowser": true,
            "launchUrl": "swagger",
            "environmentVariables": {
              "ASPNETCORE_ENVIRONMENT": "Development"
            }
          },
          "oauth_youtube": {
            "commandName": "Project",
            "dotnetRunMessages": "true",
            "launchBrowser": true,
            "launchUrl": "swagger",
            "applicationUrl": "http://localhost:5001;http://localhost:5000",
            "environmentVariables": {
              "ASPNETCORE_ENVIRONMENT": "Development"
            }
          }
        }
       
    

Criaremos uma nova rota para o Facebook oauth

      
        namespace oauth_youtube.Controllers
        {
            [ApiController]
            [Route("[controller]")]
            public class Home : ControllerBase
            {
            
              [HttpGet]
              [Route("facebook-oauth")]
              public ActionResult FacebookOauth()
              {
                  return Redirect("/dsd");
              }
            }
        }
       
    

Vamos inicializar a aplicação que irá redirecionar para o swagger:

      
        dotnet watch run
       
    

Configurando a URL do Facebook no projeto

Vamos criar a pasta Servicos e o arquivo OauthConfig no projeto, então teremos a estrutura:

  • OAUTH_YOUTUBE
    • Services
      • OauthConfig.cs

Vamos instalar o pacote Newtonsoft.Json, para ler o arquivo de configuração appsetting.

      
        dotnet add package Newtonsoft.Json --version 13.0.3
       
    

Na classe Services, teremos toda a configuração que precisamos para que o usuário faça login.

      
        using System;
        using System.IO;
        using Newtonsoft.json.Linq

        namespace oauth_youtube.Services
        {
          public class OauthConfig
          {
              public OauthConfig()
              {
                JToken jAppSettings = JToken.Parse(File.ReadAllText(Path.Combine(Environment.CurrentDirectory, "appsettings.json")));                
                this.ClientId = jAppSettings["oauth"]["client_id"].ToString();
                this.AppSecret = jAppSettings["oauth"]["app_secret"].ToString();
                this.RedirectUri = jAppSettings["oauth"]["redirect_uri"].ToString();
                this.Version = jAppSettings["oauth"]["version"].ToString();
              }

              public string ClientId { get; set;}
              public string AppSecret { get; set;}
              public string RedirectUri { get; set;}
              public string Version { get; set;}
          } 
        }
       
    

No arquivo appsettings.json, teremos as configuações que iremos criar no site do Facebook.

      
        "oauth": {
          "client_id": "***********",
          "app_secret": "*********",
          "redirect_uri": "https://localhost:5001/facebook-oauth",
          "version": "v9.0"
       
    

No método FacebookOauth, vamos instanciar a classe OauthConfig :

      
        namespace oauth_youtube.Controllers
        {
            [ApiController]
            [Route("[controller]")]
            public class Home : ControllerBase
            {
            
              [HttpGet]
              [Route("/facebook-oauth")]
              public ActionResult FacebookOauth()
              {
                  var oauthConfig = new OauthConfig();

                  return Redirect($"https://graph.facebook.com/oauth/authorize?client_id={oauthConfig.ClientId}?redirect_uri={oauthConfig.RedirectUri");
              }
            }
        }
       
    

Configurar a conta do Facebook

Ao fazer login com sua conta da empresa no Facebook, localizar o site developers.facebook.com, para criar o app e configurar as chaves client_id e app_secret.

Também é necessário autorizar as urls. Neste caso, as urls serão:

  • https://localhost:5001
  • https://localhost

Acessar o endpoint facebook-oauth

Vamos acessar o endpoint https://localhost5001/facebook-oauth para obtermos o código que o Facebook irá retornar e assim, faremos o segundo redirect com a autorização da chave que iremos precisar.

Para isso vamos alterar o método FacebookOauth para receber o parâmetro code.

      
        namespace oauth_youtube.Controllers
        {
            [ApiController]
            [Route("[controller]")]
            public class Home : ControllerBase
            {
            
              [HttpGet]
              [Route("/facebook-oauth")]
              public ActionResult FacebookOauth(string code = "")
              {
                  var oauthConfig = new OauthConfig();
                  if(string.IsNullOrEmpty(code)){
                    return Redirect($"https://graph.facebook.com/oauth/authorize?client_id={oauthConfig.ClientId}?redirect_uri={oauthConfig.RedirectUri");
                  }
              }
            }
        }
       
    

Caso o parametro code não seja nulo ou vazio, faremos a requisição Http para que seja enviado o token através do parâmetro code.

Para isso iremos utilizar o HttpWebRequest.

      
        using System.Net;
        using System.;
        using Newtonsoft.json.Linq
        namespace oauth_youtube.Controllers
        {
            [ApiController]
            [Route("[controller]")]
            public class Home : ControllerBase
            {
            
              [HttpGet]
              [Route("/facebook-oauth")]
              public ActionResult FacebookOauth(string code = "")
              {
                  var oauthConfig = new OauthConfig();
                  if(string.IsNullOrEmpty(code)){
                    return Redirect($"https://graph.facebook.com/oauth/authorize?client_id={oauthConfig.ClientId}?redirect_uri={oauthConfig.RedirectUri");
                  }
                  string json = string.Empty;
                  HttpWebRequest request = (HttpWebRequest)webRequest.Create($"https://graph.facebook.com/{oauthConfig.Version}/oauth/access_token?client_id={oauthConfig.ClientId}&redirect_uri={oauthConfig.RedirectUri}&client_secret={oauthConfig.AppSecret}&code={code}");
                  HttpWebRequest response = (HttpWebRequest)request.GetResponse();
                  if(response.StatusCode == HttpStatusCode.OK)
                  {
                    Stream receiveStream = response.GetResponseStream();
                    StreamReader readStream = new StreamReader(receiveStream);
                    json = readStream.ReadToEnd();
                    response.close();
                    readStream.close();
                  }
                  var oauthToken = JsonConvert.DeserializeObject< OauthToken>(json);
                  return Redirect($"https://graph.facebook.com/me?fields=name, gender, birthday, picture.width(320).height(320)&access_token={oauthToken.access_token}");
              }
            }
        }
       
    

Com o retorno do json, vamos inserí-lo dentro de um record.

Criaremos uma nova pasta chamada Records e um arquivo chamado OauthToken.cs para armazenar os campos que são retornados do Facebook

      
        using System;
        using System.IO;
        using Newtonsoft.json.Linq

        namespace oauth_youtube.Records
        {
          public record OauthToken
          {
            public string access_token { get; set;}
            public string token_type { get; set;}
            public string expires_in { get; set;}
          } 
        }