Tutorial de confirmação de e-mail de inscrição de usuário Ruby On Rails

Aprender rails é muito fácil hoje em dia com a abundância de tutoriais incríveis por aí, porém em minha pesquisa não consegui encontrar um bom tutorial sobre como construir um sistema de confirmação de e-mail para inscrição de usuário (você sabe o tipo onde você deve clicar um link em um e-mail para confirmar se o endereço de e-mail é realmente seu). Depois de passar algum tempo tentando descobrir, achei que seria bom compartilhá-lo para que você não perca tempo integrando essa funcionalidade indispensável.

A primeira coisa a fazer para configurar a confirmação de e-mail para um aplicativo rails 4 é adicionar uma coluna de e-mail confirmado à tabela de usuários. Para aplicativos mais complexos, geralmente é recomendado usar uma gema de máquina de estado, como máquina de estado ou transições, que permite ao usuário existir em vários estados (por exemplo, inativo, ativo, suspenso, etc.), mas para este exemplo, vamos mantê-lo simples e apenas usar uma coluna booleana na tabela de usuários que permite que o usuário seja inativo ou ativo. Também adicionaremos uma coluna para conter o token de confirmação exclusivo que usaremos para verificar o usuário. Para fazer isso, use o comando generate no terminal dentro da pasta raiz do aplicativo rails:

rails generate migration add_email_confirm_column_to_users email_confirmed:boolean confirm_token:string

Isso deve criar o seguinte arquivo de migração (observe que a adição :default => falsedeverá ser feita manualmente):

class AddEmailConfirmColumnToUsers <     ActiveRecord::Migration
def change
add_column
:users, :email_confirmed, :boolean, :default => false
add_column
:users, :confirm_token, :string
end
end

Execute para migrar as mudanças para o modelo de usuários.rake db:migrate

O próximo item da lista é atualizar o arquivo routes.rb. Existem algumas maneiras de implementar isso e, neste exemplo, escolhi manter todas as ações dentro do controlador de usuários. Para insights sobre a outra opção, que seria criar um novo controlador especificamente para a tarefa de confirmar um e-mail de usuários, consulte o episódio do railscasts sobre a implementação da funcionalidade de redefinição de senha para seu aplicativo Rails. Como estamos no controlador de usuários, temos que tornar a ação email_confirmed um membro do recurso do usuário, da seguinte forma:

resources :users do
member
do
get :confirm_email
end
end

Agora que isso está configurado, podemos passar à criação do e-mail que será enviado a um novo usuário quando ele se registrar em seu site. Rails tem uma poderosa magia de e-mail embutida que abstrai o funcionamento real sob o capô longe de nós, meros mortais, e neste estágio tudo que você precisa saber é que funciona. Primeiro faça o arquivo controllers / mailers / user_mailer.rb e insira o seguinte código:

class UserMailer < ActionMailer::Base
default :from => "me@mydomain.com"

def registration_confirmation(user)
@user = user
mail
(:to => "#{user.name} <#{user.email}>", :subject => "Registration Confirmation")
end

Externizei o endereço de envio padrão (você provavelmente deseja atualizá-lo com seu endereço de e-mail) do método de confirmação de registro (usuário) para que ele se aplique a quaisquer outros métodos no arquivo mailer.rb do usuário, mas você também pode incluí-lo dentro do método se você gostar. Neste arquivo, as variáveis ​​user.name e user.email referem-se às colunas de nome e e-mail na tabela de usuário que você provavelmente já configurou anteriormente, mas talvez com convenções de nomenclatura diferentes. Altere as variáveis ​​para refletir seu esquema de nomenclatura específico.

Após configurar o método fiz uma view para o email chamado . Você provavelmente também desejará configurar uma versão html deste arquivo, mas iremos apenas com a versão de texto para o propósito deste tutorial (novamente certifique-se de alterar o nome da variável user.name para refletir seu esquema de nomenclatura).views/user_mailer/registration_confirmation.text.erb

Hi <%= @user.name %>,

Thanks for registering! To confirm your registration click the URL below.

<%= confirm_email_user_url(@user.confirm_token) %>

Como você pode ver aqui, há uma referência a um token de confirmação que ainda não criamos, então agora é um bom momento para fazer isso. Em models / user.rb, crie um método privado chamado token de confirmação com o seguinte código:

private
def confirmation_token
if self.confirm_token.blank?
self.confirm_token = SecureRandom.urlsafe_base64.to_s
end
end

Aqui, usamos a funcionalidade embutida para gerar uma string aleatória e atribuí-la para confirmar o token. Essa string aleatória exclusiva é então inserida no e-mail que é enviado ao usuário e é usada para identificar qual usuário verificar. Enquanto estamos nisso, podemos criar o retorno de chamada que garante que o token de confirmação seja gerado e inserido na tabela de usuários quando um novo usuário for criado. Para fazer isso, basta adicionar o seguinte no topo do seu arquivo models / user.rb:

before_create :confirmation_token

Com toda essa configuração, podemos garantir que o e-mail seja enviado a um usuário quando ele criar uma nova conta. Para fazer isso, adicione à ação de criação em controllers / users_controller.rb. Minha ação de criação completa se parece com isto:UserMailer.registration_confirmation(@user).deliver

def create
@user = User.new(user_params)
if @user.save
UserMailer.registration_confirmation(@user).deliver
flash
[:success] = "Please confirm your email address to continue"
redirect_to root_url

else
flash
[:error] = "Ooooppss, something went wrong!"
render
'new'
end
end

Observe que eu os redireciono para o URL raiz em vez de acessá-los após criarem suas contas. Em meus controladores / sessões de arquivo controller.rb criar ação que eu uso para conectar os usuários, adicionei uma instrução if / else extra aninhada dentro da instrução if / else inicial para verificar se o campo email_confirmed está definido como verdadeiro ou falso para permitir apenas um usuário para entrar se seu e-mail foi confirmado. Caso contrário, eles são redirecionados para a página de login novamente e solicitados a ativar sua conta. A ação de criação do controlador de sessões agora se parece com isto (embora a sua possa ser um pouco diferente dependendo do seu trabalho anterior):

def create
user
= User.find_by_email(params[:email].downcase)
if user && user.authenticate(params[:password])
if user.email_confirmed
sign_in user

redirect_back_or user

else
flash
.now[:error] = 'Please activate your account by following the
instructions in the account confirmation email you received to proceed'

render
'new'
end
else
flash
.now[:error] = 'Invalid email/password combination' # Not quite right!
render
'new'
end
end

Se você quiser descobrir como eu construí a funcionalidade de minhas sessões, verifique o estelar Tutorial Hartl Rails. É grátis!

Por fim, chegamos à última peça do quebra-cabeça que é a ação de e-mail de confirmação no arquivo controllers / users controller.rb. Esta é a ação que o link do email procura quando clicado. Ele pega a string aleatória no campo do token de confirmação na tabela de usuários e a usa para identificar qual usuário verificar. Se encontrar um usuário que corresponda à string aleatória no campo do token de confirmação , ele define o campo do token de confirmação como verdadeiro e limpa o campo do token de confirmação para invalidar um clique subsequente no link agora expirado. Minha ação confirm_email tem a seguinte aparência:

def confirm_email
user
= User.find_by_confirm_token(params[:id])
if user
user
.email_activate
flash
[:success] = "Welcome to the Sample App! Your email has been confirmed.
Please sign in to continue."

redirect_to signin_url

else
flash
[:error] = "Sorry. User does not exist"
redirect_to root_url

end
end

Ok, então na verdade essa não foi a última coisa, como você deve ter notado os olhos de águia. Há uma chamada para um método de ativação de email na linha user.email activate e este método ainda não existe. Eu o criei no arquivo models / user.rb e se parece com isto (contém toda a lógica para manipular o modelo, então é por isso que vai no arquivo de modelo e é então chamado do controlador):

def email_activate
self.email_confirmed = true
self.confirm_token = nil
save
!(:validate => false)
end

O protege contra a validação de senha indesejada que tenho em meu modelo de usuário (verifico para ter certeza de que a senha existe e tem um comprimento mínimo de 6 caracteres ). Isso não foi abordado neste tutorial, mas pensei em deixá-lo, pois a maioria de vocês terá uma funcionalidade semelhante e isso gerará um erro se a validação não for ignorada.(:validate => false)validates :password, length: { minimum: 6 }

Portanto, agora você deve ter uma confirmação de e-mail totalmente funcional trabalhando em seu aplicativo Rails. Vá em frente, crie um novo usuário e teste-o para ter certeza de que está funcionando.