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 parafalse
.
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 }