Primeirona: Autenticação

Table of Contents

1 Primeirona (continuação)

1.1 Ambientes

Este é um bom momento para explicar que o Rails trabalha com três ambientes: desenvolvimento, testes e produção. Cada um pode ter seu conjunto de gemas e seu próprio banco de dados. São apenas conjuntos de configurações, descritas nos arquivos em config/environments. Para criar um ambiente novo, basta incluir um arquivo naquele diretório, seguindo o padrão.

1.2 Autenticação com Devise

Temos uma aplicação praticamente completa. No entando qualquer pessoa que visite as páginas consegue alterar o banco. Queremos restringir o acesso apenas aos usuários cadastrados.

A gema devise cuida de todo o processo, construindo um modelo básico para usuário e gerando as visões e controladores.

Como padrão, as visões usam erb, portanto vamos instalar também uma gema para conversão erb \(\rightarrow\) haml. Esta última gema serve apenas durante o desenvolvimento, pois na produção as páginas já estarão convertidas.

Assim, colocamos no final do Gemfile:

gem 'devise'
gem 'erb2haml', group: :development

E naturalmente rodamos bundle install.

Agora podemos gerar os modelos, de forma parecida com o scaffold, mas usaremos o devise:

rails g devise:install

Ao final aparecerão uma lista de coisas para fazer:

  • atualizar os ambiente (environment) de desenvolvimento para gerenciar emails. Basta incluir a linha mostrada.
  • garantir que exista uma rota para root, já fizemos.
  • colocar parágrafos para alert e notice. Já fizemos para notice, vamos colocar a outra no cabeçalho (navbar) e completar com outras opções.
!!!
%html
  %head
    %meta{:content => "text/html; charset=UTF-8", "http-equiv" => "Content-Type"}/
    %title Primeirona
    = csrf_meta_tags
    = csp_meta_tag
    = stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload'
    = javascript_include_tag 'application', 'data-turbolinks-track': 'reload'
  %body
    %nav.navbar.navbar-default.container-fluid
      .collapse.navbar-collapse
        .navbar.navbar-nav.navbar-left
          .btn= link_to t(:list), apelidos_path
          .btn= link_to t(:new), new_apelido_path
          .btn= link_to 'Tipos', tipos_path
          .btn= link_to 'Novo tipo', new_tipo_path
        .navbar.navbar-nav.navbar-right
          - if notice
            %span.notice= notice
          - if alert
            %span.alert= alert  
          - if user_signed_in?
            %strong= current_user.email
            %button= link_to 'Editar', edit_user_registration_path
            %button= link_to 'Sair', destroy_user_session_path, method: :delete
          - else
            %button= link_to 'Entrar', new_user_session_path
            %button= link_to 'Cadastrar', new_user_registration_path
    = yield

Se quiser, ajuste o css para estas classes.

  • Finalmente, gerar as visões default, aproveitamos para converter os arquivos erb.
rails g devise:views
rake haml:replace_erbs

O próximo passo é gerar o modelo de usuário (user)

rails g devise user
rake db:migrate

Agora precisamos garantir que os usuários estejam logados para visitar as páginas. Isso é feito em application_controller.rb. Já que vamos mexer, colocamos mais segurança também.

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  before_action :set_locale
  before_action :authenticate_user!
  def set_locale
    I18n.locale = params[:locale] || I18n.default_locale
  end
end

Na página de entrada (views/manda/index.html.haml), vamos arrumar o conteúdo para apontar para as outras páginas.

%center
  %h1.titulo Apelidos e Tipos

  %p= link_to 'Apelidos', apelidos_path
  %p= link_to 'Tipos', tipos_path

1.2.1 Email de confirmação

É bom verificar se o email existe. Um método é mandar uma mensagem para o usuário confirmar que recebeu e completar o registro. Basta colocar um símbolo a mais no modelo de usuário (user.rb). Adicionamos :confirmable.

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable,
         :confirmable
end

Isso implica em uma alteração no banco.

rails g migration add_confirmable_to_devise

Como em princípio existem usuários cadastrados, precisamos ajustar a migração na mão. Uma migração contém 3 métodos:

  • change para alterações em geral
  • up para fazer a migração
  • down para desfazer a migração.

Precisamos das seguintes colunas adicionais:

  • token de confirmação
  • data da confirmação
  • data de envio da mensagem
  • índice único para o token

Queremos também autenticar automaticamente todos os usuários já cadastrados.

Vamos alterar a migração gerada pelo comando acima, veja em db/migrate. Apagamos o método change e definimos up e down.

class AddConfirmableToDevise < ActiveRecord::Migration[5.2]
  # def change
  # end
  def up
    add_column :users, :confirmation_token, :string
    add_column :users, :confirmed_at, :datetime
    add_column :users, :confirmation_sent_at, :datetime
    add_index :users, :confirmation_token, unique: true
    User.all.update_all confirmed_at: DateTime.now
  end

  def down
    remove_columns :users, :confirmation_token, :confirmed_at,
                   :confirmation_sent_at
  end
end

E executar a migração (rake db:migrate).

Como estamos usando mensagens de email, precisamos também configurá-las. Vamos editar config/initializers/devise.rb e alterar algumas opções. Ao invés de mostrar o arquivo todo, vou listá-las aqui:

  • config.mailer_sender, coloque um endereço de email adequado.
  • config.reconfirmable, mude para false.

Não precisamos até agora das visões de usuário, mas vamos querer pelo menos a visão de mensagens. Vamos gerar todas:

rails g devise:views user
rake haml:replace_erbs

Veja os arquivos em app/views/user/mailer.

Falta configurar o envio de emails. Usaremos a gema mailcatcher para visualizar mensagens no browser. O mailcatcher é um serviço que escuta menagens de email (smtp) na porta 1025 e apresenta por http na porta 1080.

gem install mailcatcher

A configuração deve ser feita para o ambiente de desenvolvimento, portanto em config/environments/developmentrb. Altere config.action_mailer.raise_delivery_errors para true e adicione as seguintes linhas:

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = { address: 'localhost', port: 1025 }

Author: Marco Dimas Gubitoso

Created: 2019-04-18 qui 16:23

Emacs 25.2.2 (Org mode 8.2.10)

Validate