Salesforce OAuth em aplicações Rails

Publicado por Geison Biazus no dia dev

O protocolo OAuth (Open Authorization) permite que um usuário forneça acesso a funcionalidades limitadas de uma aplicação para outra. Ao clicar em um link da aplicação A, o usuário é redirecionado para uma tela da aplicação B, onde ele vai permitir que a aplicação utilize sua conta e credenciais para executar determinadas ações.

A gem OmniAuth padroniza a autorização utilizando OAuth em aplicações ruby. Com ela é possível que os desenvolvedores criem strategies para conectar em aplicações específicas, ou seja, um desenvolvedor pode criar uma gem que utilize o padrão do OmniAuth para conectar com a aplicação de seu interesse.

Já existem strategies prontas para várias aplicações, o repositório oficial do OmniAuth fornece uma lista de todas elas.

Neste post, vou mostrar como conectar com a aplicação Salesforce utilizando a gem omniauth-salesforce. Essa aplicação de exemplo mostra o resultado da implementação desse post, o código fonte se encontra no GitHub.

Criando um aplicativo no Salesforce

Antes de configurar nossa aplicação Rails, é preciso criar e configurar um aplicativo dentro do Salesforce. Para isso é necessário possuir uma conta, caso não possua, crie uma conta de desenvolvedor na página de desenvolvedores do Salesforce.

Estando logado, acesse a página “Configuração”. Depois clique em “Criar” e em seguida em “Aplicativos” no menu do lado esquerdo. Nessa página existe uma lista entitulada “Connected Apps”, clique em “Novo”, ao lado do título, como mostra a imagem.

Botão apra criar uma nova aplicação

Marque a opção “Habilitar as Configurações do OAuth” e preencha as opções conforme mostra a imagem a seguir.

Formulário da nova aplicação

O campo “URL da chamada” indica o endereço de callback após a autorização, ou seja, é o endereço que o usuário será redirecionado após ele autorizar o uso do Salesforce para a nossa aplicação.

Os “Escopos OAuth selecionados” são os acessos que nossa aplicação pedirá permissão para o Salesforce. A opção “Desempenhe solicitações em seu nome a qualquer momento…” serve para que nossa aplicação utilize o acesso do usuário do Salesforce por tempo indeterminado, sem que seja necessária uma nova autenticação por acesso.

Terminando, clique em “Salvar” e a seguinte tela irá surgir:

Informações da nova aplicação

Nessa tela, anote as informações “Chave do cliente” e “Segredo do cliente”. Esses dados serão utilizados na configuração da gem da nossa aplicação Rails.

Recomendo que você crie um aplicativo para desenvolvimento e outro para produção dentro do Salesforce, assim no aplicativo de produção a URL de chamada ficaria com o domínio da sua aplicação ao invés de “localhost:3000”. Essa URL precisa ter o mesmo domínio que o usuário acessa nossa aplicação, caso contrário a autorização falhará.

Instalando e configurando a gem omniauth-salesforce

Abra seu arquivo Gemfile e adicione a seguinte linha:

1
gem "omniauth-salesforce"

Para instalar a nova gem execute o comando:

1
$ bundle install

Vamos manter as configurações do aplicativo em um arquivo YML. Para isso crie um novo arquivo na pasta config chamado salesforce.yml e nele coloque as seguintes informações:

1
2
3
4
5
6
7
8
9
10
development: &default
  client_key: # chave do cliente do seu aplicativo no Salesforce
  client_secret: # segredo do cliente do seu aplicativo no Salesforce

test:
  <<: *default

production:
  client_key: # chave do cliente do seu aplicativo de produção no Salesforce
  client_secret: # segredo do cliente do seu aplicativo de produção no Salesforce

Nos itens client_key e client_secret informe os dados dos aplicativos de desenvolvimento e de produção criados no Salesforce. No diretório config/initializers crie um arquivo chamado salesforce.rb com o seguinte conteúdo:

1
2
3
4
5
$salesforce_config = YAML.load_file(File.join(Rails.root, 'config', 'salesforce.yml'))[Rails.env]

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :salesforce, $salesforce_config["client_key"], $salesforce_config["client_secret"]
end

Com isso a gem está configurada. Agora precisamos criar o link para a página de autorização e implementar a action de callback.

Implementando controllers e views

Precisamos de um link que, ao ser acessado, redirecionará o usuário para a página de autorização do Salesforce. Neste exemplo vamos adicionar esse link na pagina inicial da aplicação. Para isso, vamos gerar um controller e uma view. Caso sua aplicação já possua essa página, você pode pular essa etapa. Execute o seguinte comando:

1
$ rails g controller home index

Adicione a seguinte linha no arquivo config/routes.rb:

1
root 'home#index'

No arquivo app/views/index.html.erb, adicione:

1
<%= link_to 'Connect with Salesforce', '/auth/salesforce' %>

A URL /auth/salesforce não se encontra no arquivo routes.rb, pois ela é gerada automaticamente com a gem omniauth-salesforce.

Quando o usuário clicar nesse link, ele será redirecionado para a página de autorização do Salesforce. Ao permitir o acesso, ele será novamente redirecionado para a nossa aplicação na URL cadastrada no aplicativo dentro do Salesforce (http://localhost:3000/auth/salesforce/callback). Logo, precisamos de uma rota e uma action para tratar o retorno.

Para isso, digite o seguinte comando para criar um novo controller:

1
$ rails g controller salesforce callback

Agora vamos alterar o arquivo config/routes.rb para escutar a URL configurada no Salesforce. Adicione a seguinte linha no arquivo:

1
get 'auth/salesforce/callback', to: 'salesforce#callback'

No arquivo salesforce_controller.rb, adicione a action para tratar o retorno:

1
2
3
4
5
6
7
def callback
  credentials = env["omniauth.auth"]["credentials"]
  session['token'] = credentials["token"]
  session['refresh_token'] = credentials["refresh_token"]
  session['instance_url'] = credentials["instance_url"]
  redirect_to root_path # alguma URL da sua aplicação
end

Na action acima, obtemos algumas informações retornadas pelo Salesforce. Neste caso, armazenamos as mesmas na sessão do usuário, mas é possível armazená-las no banco de dados e reutillizá-las sem a necessidade de solicitar o acesso novamente.

Com essas informações você pode utilizar outras gems, como databasedotcom ou restforce, para acessar a API do Salesforce e obter ou manipular os dados do usuário.

Tratando falhas na autorização

Caso o usuário recuse o acesso ao Salesforce, será lançada uma excessão na aplicação. Para tratar adicione as seguintes linhas no arquivo config/initializers/salesforce.rb:

1
2
3
OmniAuth.config.on_failure = Proc.new do |env|
  SalesforceController.action(:failure).call(env) if env["omniauth.strategy"].is_a? OmniAuth::Strategies::Salesforce
end

No salesforce_controller.rb, crie a action:

1
2
3
4
def failure
  flash[:error] = 'Authorization failure'
  redirect_to root_path
end

Com isso o usuário será redirecionado para a action failure sempre que a autorização falhar.

Aprendizado

O protocolo OAuth oferece benefícios tanto para os usuários quanto para os desenvolvedores. Com ele as aplicações podem se integrar e compartilhar recursos sem a necessidade de replicar os mesmos em cada aplicação. Além disso, através da troca de tokens, a integração se torna mais segura, uma vez que os desenvolvedores não necessitam armazenar as credencias do usuário. Os usuários, por sua vez, sabem exatamente quais recursos serão compartilhados, pois o acesso só é liberado após a aprovação do mesmo.

Geison Biazus

Geison Biazus

Full Stack Developer

Comentários