wevolve logo
Guia completo para configurar OAuth em um app Ruby on Rails API com Devise Auth Token
Início / Blog / Guia completo para configurar OAuth em um app Ruby on Rails API com Devise Auth Token

Guia completo para configurar OAuth em um app Ruby on Rails API com Devise Auth Token

Por Richard S. Tempo de leitura 9 minutos

Com o crescente interesse em aplicativos web e móveis, garantir a segurança e a facilidade de acesso dos usuários é fundamental para proporcionar uma experiência positiva. Nesse contexto, o OAuth (Open Authorization) se destaca como uma solução poderosa para autenticação e autorização seguras entre aplicativos.

Ao desenvolver aplicativos Ruby on Rails, integrar o OAuth com a autenticação do usuário é um desafio comum. No entanto, com o uso da biblioteca “Devise Auth Token” e OmniAuth, é possível simplificar e otimizar esse processo.

Neste guia completo, vamos explorar o passo a passo para configurar o OAuth em um aplicativo Ruby on Rails, utilizando a eficiente biblioteca “Devise Auth Token”. Ao seguir este tutorial, você estará apto a implementar uma solução robusta de autenticação por token em seu aplicativo, oferecendo aos usuários a opção de login por meio de provedores de terceiros, como Google, Facebook, GitHub entre outros, proporcionando segurança aos dados e uma experiência de usuário mais fluída.

Vamos mergulhar nas etapas para configurar com sucesso o OAuth em um app Ruby on Rails API. Siga os passos e transforme a autenticação do seu aplicativo em uma experiência segura e otimizada.

Por que utilizar autenticação de terceiros?

Utilizar a autenticação de terceiros traz uma série de benefícios significativos para o desenvolvimento de aplicativos web e móveis. Algumas das principais razões pelas quais a autenticação de terceiros através do OAuth é uma escolha vantajosa:

  1. Simplifica o processo de registro e login: Com o OAuth, os usuários podem se inscrever e fazer login em um aplicativo usando suas credenciais de contas existentes em provedores de terceiros, como Google, Facebook, Twitter, GitHub, etc. Isso elimina a necessidade de criar e lembrar de novas senhas, tornando o processo mais simples e rápido para os usuários.

  2. Maior segurança e confiabilidade: Ao utilizar a autenticação de terceiros, o aplicativo não precisa armazenar senhas de usuário em seu banco de dados. Em vez disso, o fluxo de autenticação é delegado aos provedores de terceiros que têm medidas robustas de segurança para proteger as credenciais dos usuários. Isso reduz a probabilidade de ataques de força bruta ou vazamentos de dados relacionados às senhas.

  3. Redução do churn de usuários: Com a facilidade de login proporcionada pelo OAuth, os usuários são mais propensos a concluir o processo de registro e a permanecer engajados com o aplicativo. A complexidade do registro tradicional pode levar a taxas mais altas de abandono durante o processo de inscrição.

  4. Acesso a informações do perfil do usuário: Com a permissão adequada do usuário, o aplicativo pode acessar algumas informações do perfil do usuário fornecidas pelo provedor de terceiros. Isso pode ser útil para personalizar a experiência do usuário e oferecer recursos relevantes.

  5. Padrão de autenticação estabelecido: O OAuth é amplamente aceito e adotado como um padrão para autenticação de terceiros. Isso significa que os desenvolvedores podem contar com a solidez e a segurança do protocolo, evitando a necessidade de criar soluções personalizadas de autenticação.

OAuth oferece uma experiência de login mais conveniente e segura para os usuários, ao mesmo tempo em que reduz a complexidade e a sobrecarga de gerenciamento de contas para os desenvolvedores. É uma escolha inteligente para qualquer aplicativo moderno que valoriza a segurança e a satisfação do usuário.

O que vou precisar para começar?

Neste tutorial vamos utilizar a versão 3.1.4 do Ruby, Rails 7.0.4.3 e banco de dados sqlite. O ambiente utilizado neste tutorial é Ubuntu (linux).

Você pode utilizar outro banco de dados passando o parametro “-d=”, ex.: -d=postgresql, ficando:

$ rails new oauth_login --api -d=postgresql

Neste exemplo usaremos o sqlite mesmo:

$ rails new oauth_login --api

Após realizar a instalação, vamos entrar no diretório e instalar algumas gems:

$ cd oauth_login

Adicione as seguintes gems:

/oauth_login$ bundle add devise_token_auth omniauth-google-oauth2 omniauth-rails_csrf_protection

Aqui adicionamos 3 gems:

  1. devise_token_auth: É uma gem que se integra com o Devise, uma popular biblioteca de autenticação para Ruby on Rails, permitindo adicionar autenticação de token ao seu aplicativo.

  2. omniauth-google-oauth2: Essa gem é uma estratégia do OmniAuth para autenticação com o Google através do protocolo OAuth 2.0.

  3. omniauth-rails_csrf_protection: Esta gem é uma extensão do OmniAuth que adiciona proteção CSRF (Cross-Site Request Forgery) aos seus fluxos de autenticação. O CSRF é um tipo comum de ataque que tenta explorar a confiança entre um usuário autenticado e um site. Essa gem ajuda a mitigar esse tipo de ataque, fornecendo uma camada adicional de segurança para o processo de autenticação.

Vamos executar agora a instalação do devise token auth:

/oauth_login$ rails g devise_token_auth:install User auth

Você pode modificar o caminho da rota padrão (auth) mudando o “auth” para o nome desejado, ex.:

/oauth_login$ rails g devise_token_auth:install User users

Neste tutorial, seguiremos os padrões.

Rode as migrações executando:

/oauth_login$ rails db:migrate

Caso ocorre algum erro, experimente adicionar o seguinte ao seu model User.rb:
app/models/user.rb:

class User < ActiveRecord::Base
  extend Devise::Models

  # restante dos códigos

Rode as migrações novamente.
Agora vamos criar um arquivo de configuração do omniauth dentro da pasta initialize do rails:
config/initializer/omniauth.rb:

Rails.application.config.middleware.use OmniAuth::Builder do
  OmniAuth.config.allowed_request_methods = %i[post get]

  provider :google_oauth2, Rails.application.credentials.dig(:omniauth, :google, :key),
  Rails.application.credentials.dig(:omniauth, :google, :secret), scope: 'email,profile'
end

Abaixo uma breve explicação:

  1. Rails.application.config.middleware.use OmniAuth::Builder do: Esta linha inicia a configuração do middleware do OmniAuth no aplicativo Rails.

  2. OmniAuth.config.allowed_request_methods = %i[post get]: Essa linha define os métodos de solicitação HTTP permitidos para o fluxo de autenticação do OmniAuth. Neste caso, os métodos “POST” e “GET” são permitidos. Isso é importante porque o fluxo de autenticação OAuth do OmniAuth.

  3. **provider :google_oauth2, Rails.application.credentials.dig(:omniauth, :google, :key), Rails.application.credentials.dig(:omniauth, :google, :secret), scope: 'email,profile'**: Aqui, estamos configurando o provedor de autenticação do Google OAuth 2.0 usando o OmniAuth.

    • provider :google_oauth2: Indica que estamos configurando o provedor para autenticação com o Google OAuth 2.0.

    • Rails.application.credentials.dig(:omniauth, :google, :key) e Rails.application.credentials.dig(:omniauth, :google, :secret): Acesse as credenciais armazenadas no arquivo credentials.yml.enc do Rails, que são usadas para identificar o aplicativo no provedor de autenticação (Google). Essas credenciais geralmente incluem a chave do cliente (client key) do Google, que é um identificador exclusivo do aplicativo.

    • scope: 'email,profile': Define as permissões que o aplicativo solicitará ao usuário durante o processo de autenticação. Neste caso, o aplicativo solicita acesso ao email do usuário e ao perfil público.

Agora que configuramos o omniauth, vamos criar uma chave OAuth. Para isso, entre no console do google acessando https://console.cloud.google.com/welcome

Após o acesso, selecione um projeto ou crie um novo clicando em “Novo projeto”

Clique em APIs e serviços:

Agora em credenciais:

Clique em “Criar credenciais” e selecione “ID do Cliente OAuth”:

Você deverá criar uma tela de concentimento para utilizar este serviço. Siga as etapas da criação e após sua conclusão, clique novamente em “Credenciais”, “Criar credenciais” e “ID do cliente OAuth”

Selecione o tipo do aplicativo:

Na URIs de redirecionamento autorizados, adicione:
http://localhost:3000/omniauth/google_oauth2/callback e clique em “Criar”

Vamos adicionar as chaves ao arquivo de credenciais do rails:

Acesse o terminal novamente e vamos prosseguir com a edição:

Para linux:

/oauth_login$ EDITOR="nano" rails credentials:edit

Seu arquivo credentials deve ficar da seguinte forma:

# aws:
#   access_key_id: 123
#   secret_access_key: 345

# Used as the base secret for all MessageVerifiers in Rails, including the one protecting cookies.
secret_key_base: 8147112cd2d1bc0d9b00b4aa46c9f4eab8da8f0200354c7f0c81c45e396a2b936dc4d341a5c67a8ff26c4046815a4928e7>

omniauth:
  google:
    key: "Seu cliente"
    secret: "sua chave"

Salve o arquivo pressionando CTRL + X, depois Y e então “ENTER”

Agora que temos a chave configurada corretamente, precisamos modificar o controller padrão de autenticação do devise token auth. Para isso, vamos criar o seguite:
app/controllers/omniauth_callbacks_controller.rb:

class OmniauthCallbacksController < DeviseTokenAuth::OmniauthCallbacksController

  def omniauth_success
    get_resource_from_auth_hash
    set_token_on_resource
    create_auth_params

    if confirmable_enabled?
      # don't send confirmation email!!!
      @resource.skip_confirmation!
    end

    sign_in(:user, @resource, store: false, bypass: false)

    @resource.save!

    yield @resource if block_given?

    if DeviseTokenAuth.cookie_enabled
      set_token_in_cookie(@resource, @token)
    end

    render json: { data: @resource, auth_params: @auth_params }

  rescue
    return render json: {errors: ["Houve um problema ao processar sua requisição"]}
  end

  protected

  def render_error_email_already_exists
    render json: {errors: ["Este e-mail já está sendo utilizado."]}, status: :unprocessable_entity
  end
end

Colocamos algumas modificações no controller padrão do devise auth, afim de faze-lo retornar os dados de sessão do usuário no retorno, adicionamos a linha 27:

render json: { data: @resource, auth_params: @auth_params }

Na linha 29 em diante, adicionamos um rescue, para capturarmos problemas relacionados a autenticação e assim, poder informar o usuário:

 rescue
    return render json: {errors: ["Houve um problema ao processar sua requisição"]}

Vamos adicionar uma validação de e-mail no model User.rb para evitar problemas de repetição no banco de dados:
app/models/user.rb:

# resto do código

validates :email, uniqueness: true, presence: true, allow_blank: false

Agora que criamos o controller, precisamos que o devise token auth utilize nosso controller para o omniauth:
config/routes.rb:

Rails.application.routes.draw do
  mount_devise_token_auth_for 'User', at: 'auth', controllers: {
    omniauth_callbacks: 'omniauth_callbacks'
  }
  # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html

  # Defines the root path route ("/")
  # root "articles#index"
end

Aqui modificamos o mount_devise_token_auth_for com:

, controllers: {
  omniauth_callbacks: 'omniauth_callbacks'
}

Por ultimo precisamos adicionar cookie e de sessões em nosso sistema, pois sem eles não é possível realizar a autenticação oauth em api:
config/application.rb

    config.api_only = true

    config.session_store :cookie_store, key: '_oauth_login_session'
    config.middleware.use ActionDispatch::Cookies
    config.middleware.use ActionDispatch::Session::CookieStore, config.session_options
  end
end

O application inteiro fica:

require_relative "boot"

require "rails/all"

# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)

module OauthLogin
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 7.0

    # Configuration for the application, engines, and railties goes here.
    #
    # These settings can be overridden in specific environments using the files
    # in config/environments, which are processed later.
    #
    # config.time_zone = "Central Time (US & Canada)"
    # config.eager_load_paths << Rails.root.join("extras")

    # Only loads a smaller set of middleware suitable for API only apps.
    # Middleware like session, flash, cookies can be added back manually.
    # Skip views, helpers and assets when generating a new resource.
    config.api_only = true

    config.session_store :cookie_store, key: '_oauth_login_session'
    config.middleware.use ActionDispatch::Cookies
    config.middleware.use ActionDispatch::Session::CookieStore, config.session_options
  end
end

Para testar, precisamos iniciar o servidor:

/oauth_login$ rails s

Acesse: localhost:3000/auth/google_oauth2 no navegador e escolha uma conta:

Após a escolha, você será redirecionado com os dados de acesso:

os cabeçalhos de autenticação você pode encontrar no atributo auth_params

Conclusão

Com algumas modificações e comandos, foi possível realizar uma autenticação via google de uma forma simples e rápida utilizando o devise token auth e a gem omniauth-google-oauth2.

O projeto final você encontra no github, neste link: https://github.com/05104/oauth\_login