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:
-
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.
-
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.
-
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.
-
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.
-
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:
-
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. -
omniauth-google-oauth2
: Essa gem é uma estratégia do OmniAuth para autenticação com o Google através do protocolo OAuth 2.0. -
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:
-
Rails.application.config.middleware.use OmniAuth::Builder do
: Esta linha inicia a configuração do middleware do OmniAuth no aplicativo Rails. -
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. -
**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)
eRails.application.credentials.dig(:omniauth, :google, :secret)
: Acesse as credenciais armazenadas no arquivocredentials.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