- Criar um Usuário no Banco de Dados
- Testar login de usuário
- Enviar um email de boas vindas com nome (atributo) do usuário
- Enviar email com código quando esquecer a senha
- Enviar email quando senha for alterada
- Enviar email com diferente passagem de parâmetros junto de um gif na mensagem
- Dar deploy no Heroku
- Enviar emails pelo Heroku
- Utilizar variáveis do ambiente de desenvolvimento do Heroku
rails new --api --database=postgresql -T
rails g model User name:string email:string password_digest:string
rails db:setup db:migrate
user.rb
:has_secure_password validates :email, presence: true, uniqueness: true validates :email, format: { with: URI::MailTo::EMAIL_REGEXP } validates :password, length: { minimum: 6 }, if: -> { new_record? || !password.nil? }
rails g controller User
users_controller.rb
:before_action :authorize_request, except: %i[create] before_action :find_user, except: %i[create index] def index @users = User.all render json: @users, status: :ok end def show render json: @user, status: :ok end def create @user = User.new(user_params) if @user.save render json: @user, status: :created else render json: { errors: @user.errors.full_messages }, status: :unprocessable_entity end end def update unless @user.update(user_params) render json: { errors: @user.errors.full_messages }, status: :unprocessable_entity end end def destroy @user.destroy end private def find_user @user = User.find_by_id!(params[:id]) rescue ActiveRecord::RecordNotFound render json: { errors: 'User not found' }, status: :not_found end def user_params params.permit(:name, :email, :password, :password_confirmation) end
Gemfile
:gem 'bcrypt', '~> 3.1.7' gem 'jwt'
bundle install
app/lib/json_web_token.rb
:class JsonWebToken SECRET_KEY = Rails.application.secrets.secret_key_base. to_s def self.encode(payload, exp = 24.hours.from_now) payload[:exp] = exp.to_i JWT.encode(payload, SECRET_KEY) end def self.decode(token) decoded = JWT.decode(token, SECRET_KEY)[0] HashWithIndifferentAccess.new decoded end end
rails g controller Authentication
authetication_controller.rb
:class AuthenticationController < ApplicationController before_action :authorize_request, except: :login def login @user = User.find_by_email(params[:email]) if @user&.authenticate(params[:password]) token = JsonWebToken.encode(user_id: @user.id) time = Time.now + 24.hours.to_i render json: { token: token, exp: time.strftime("%m-%d-%Y %H:%M"), id: @user.id }, status: :ok else render json: { error: 'unauthorized' }, status: :unauthorized end end private def login_params params.permit(:email, :password) end end
application_controller.rb
:def not_found render json: { error: 'not_found' } end def authorize_request header = request.headers['Authorization'] header = header.split(' ').last if header begin @decoded = JsonWebToken.decode(header) @current_user = User.find(@decoded[:user_id]) rescue ActiveRecord::RecordNotFound => e render json: { errors: e.message }, status: :unauthorized rescue JWT::DecodeError => e render json: { errors: e.message }, status: :unauthorized end end
routes.rb
:resources :users post "auth/login", to: "authentication#login"
rails s
- Testar no Insomnia (cadastro funcionando junto do login)
rails g mailer UserMailer
user_mailer.rb
:def welcome_email(user) @user = user mail(to: @user.email, subject: "[BEM VINDO(A) AO CJR CLASS]") end
views/user_mailer/welcome_email.html.erb
:<h1>Seja Bem Vindo(a) ao CJR Class</h1> <p>Você acabou de se cadastrar no nosso Mailer com o nome de: "<%= @user.name %>".</p>
users_controller.rb # create
:UserMailer.welcome_email(@user).deliver_now
development.rb
:config.action_mailer.delivery_method = :smtp config.action_mailer.smtp_settings = { address: 'smtp.gmail.com', port: 587, domain: 'cjr.org.br', user_name: 'tucazorron@gmail.com', password: 'xxxxxxxx', authentication: 'plain', enable_starttls_auto: true }
application_mailer.rb
:default from: 'tucazorron@gmail.com'
- Testar no Insomnia (vai dar certo mas o email não chega)
- Configurar no Google que Aplicativos menos seguros tenham acesso ao email
rails db:reset
- Testar no Insomnia (email vai chegar)
rails g migration AddPasswordResetColumnsToUser reset_password_token:string reset_password_sent_at:datetime
rails db:migrate
users_controller.rb
:def forgot if params[:email].blank? return render json: {error: 'Email not present'} end user = User.find_by(email: params[:email]) if user.present? user.generate_password_token! render json: {status: 'ok'}, status: :ok else render json: {error: ['Email address not found. Please check and try again.']}, status: :not_found end end def reset token = params[:token].to_s email = params[:email] if token.blank? return render json: {error: 'Token not present'} end if email.blank? return render json: {error: 'Email not present'} end user = User.find_by(email: params[:email]) if user.present? && user.password_token_valid? if user.reset_password!(params[:password]) render json: {status: 'ok'}, status: :ok else render json: {error: user.errors.full_messages}, status: :unprocessable_entity end else render json: {error: ['Link not valid or expired. Try generating a new link.']}, status: :not_found end end
users_controller.rb
:before_action :authorize_request, except: %i[create forgot reset] before_action :find_user, except: %i[create index forgot reset]
user.rb
:def generate_password_token! self.reset_password_token = generate_token self.reset_password_sent_at = Time.now.utc save! end def password_token_valid? (self.reset_password_sent_at + 4.hours) > Time.now.utc end def reset_password!(password) self.reset_password_token = nil self.password = password save! end private def generate_token SecureRandom.hex(10) end
routes.rb
:post "login/forgot_password", to: "users#forgot" post "login/reset_password", to: "users#reset"
user_mailer.rb
:def forgot_password_email(user) @user = user mail(to: @user.email, subject: "[ALTERAR MINHA SENHA]") end def reset_password_email(user) @user = user mail(to: @user.email, subject: "[NOVA SENHA]") end
views/user_mailer/forgot_password_email.html.erb
:<h1>Código para Alterar a sua Senha: <%= @user.reset_password_token %></h1>
views/user_mailer/reset_password_email.html.erb
:<h1>Senha alterada com Sucesso</h1>
users_controller.rb
:def forgot ... UserMailer.forgot_password_email(user).deliver_now ... def reset ... UserMailer.reset_password_email(user).deliver_now
- Testar no Insomnia (vai dar certo)
- Mandar email com imagem com outra passagem de parâmetros e
deliver_later
users_controller.rb
:def create ... UserMailer.with(user: @user).welcome_email.deliver_later
user_mailer.rb
:def welcome_email ... attachments['homer.gif'] = File.read('app/assets/images/homer.gif')
welcome_email.html.erb
:<%= image_tag attachments['homer.gif'].url, alt: 'Homer Pelado', class: 'photos' %>
production.rb
:config.action_mailer.delivery_method = :smtp config.action_mailer.smtp_settings = { address: 'smtp.gmail.com', port: 587, domain: 'cjr.org.br', user_name: ENV["DEFAULT_EMAIL"], password: ENV["DEFAULT_PASSWORD"], authentication: 'plain', enable_starttls_auto: true }
- Adicionar um repositório no git e enviar para lá
heroku login
heroku create nome-do-projeto
git push heroku master
heroku run rails db:migrate
- Setar as variáveis de ambiente de desenvolvimento no Heroku