• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Desenvolvimento web com Ruby on Rails (parte 6)
 

Desenvolvimento web com Ruby on Rails (parte 6)

on

  • 523 views

 

Statistics

Views

Total Views
523
Views on SlideShare
523
Embed Views
0

Actions

Likes
0
Downloads
3
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Desenvolvimento web com Ruby on Rails (parte 6) Desenvolvimento web com Ruby on Rails (parte 6) Presentation Transcript

    • Desenvolvimento Web com Ruby on Rails João Lucas Pereira de Santana gtalk | linkedin | twitter: jlucasps
    • Devise @jlucasps Solução flexível para autenticação de usuários Segue o padrão MVC Totalmente integrada com o Rails Permite várias roles autenticadas ao mesmo tempo (user, admin, member) Baseada em conceitos de módulos
    • ● Database Authenticatable ○ Criptografar a senha e armazenar em banco de dados ○ Auntenticação pode ser feita via POST ou HTTP Basic Authentication Devise @jlucasps
    • ● Token Authenticatable ○ Autenticar o usuário baseado em um token de acesso ○ Token pode ser enviado via query string ou HTTP Basic Authentication Devise @jlucasps
    • Devise @jlucasps ● Omniauthable ○ Framework de autenticação compatível com diversos providers (facebook, twitter, openId, google, github), além dos tradicionais username e password
    • Devise @jlucasps ● Confirmable ○ Enviar email com as instruções de confirmação de cadastro ● Recoverable ○ Alterar password do usuário e enviar instruções de alteração
    • Devise @jlucasps ● Registerable ○ Permite cadastar usuários para utilizarem uma aplicação ○ Editar as informações de cadastro do usuário ○ Excluir o cadastro
    • Devise @jlucasps ● Rememberable ○ Mecanimo para salvar cookies e permitir manter usuário autenticado na aplicação ● Trackable ○ Registrar quantidade de acessos, hora do acesso e IP de origem
    • Devise @jlucasps ● Timeoutable ○ Expirar a sessão caso o usuário fique um período inativo ● Validatable ○ Validação de email e password ○ Mecanismo opcional e customizável
    • Devise @jlucasps ● Lockable ○ Bloquear a conta do usuário caso haja um certo número de tentativas frustradas de acesso ○ Desbloqueio pode ser feito via email ou após um período de tempo
    • Devise @jlucasps # https://github.com/plataformatec/devise # Flexible authentication solution for Rails with Warden gem 'devise' Atualizar Gemfile Atualizar config/environments/development.rb config.action_mailer.default_url_options = { :host => 'localhost:3000' }
    • MailCatcher @jlucasps # https://github.com/sj26/mailcatcher # Catches mail and serves it through a dream. gem 'mailcatcher' Adicionar MailCatcher ao Gemfile Atualizar config/environments/development.rb config.action_mailer.delivery_method = :smtp config.action_mailer.smtp_settings = { :address => "localhost", : port => 1025 } jlucasps@lotus:/media/truecrypt1/handsonrails/first_app$ mailcatcher Starting MailCatcher ==> smtp://127.0.0.1:1025 ==> http://127.0.0.1:1080 *** MailCatcher runs as a daemon by default. Go to the web interface to quit.
    • Devise @jlucasps Após adicionar Devise ao Gemfile, execute o generator jlucasps@lotus:/media/truecrypt1/handsonrails/first_app$ rails g devise: install create config/initializers/devise.rb create config/locales/devise.en.yml =========================================== ==================== Some setup you must do manually if you haven't yet: ....
    • Devise @jlucasps <!DOCTYPE html> <html> <head> <title>FirstApp</title> <%= stylesheet_link_tag "application", :media => "all" %> <%= javascript_include_tag "application" %> <%= csrf_meta_tags %> </head> <body> <p class="notice"><%= notice %></p> <p class="alert"><%= alert %></p> <%= render :partial => 'shared/menu_top' %> <div class="container-fluid"> <div class="row-fluid"> <%= yield :sidebar %> <%= yield %> </div> <%= render :partial => 'shared/footer' %> </div> </body> </html> Configurar /app/views/layouts/application.html.erb
    • Devise @jlucasps jlucasps@lotus:/media/truecrypt1/handsonrails/first_app$ rails g devise User invoke active_record create db/migrate/20130619172147_add_devise_to_users.rb insert app/models/user.rb route devise_for :users Adicionar Devise a algum model Configurar Migration gerada e executá-la jlucasps@lotus:/media/truecrypt1/handsonrails/first_app$ rake db:migrate == AddDeviseToUsers: migrating =============================================== -- change_table(:users) -> 0.0590s -- add_index(:users, :reset_password_token, {:unique=>true}) -> 0.0007s == AddDeviseToUsers: migrated (0.0600s) ======================================
    • Devise @jlucasps class ApplicationController < ActionController::Base protect_from_forgery before_filter :authenticate_user! end Configurar ApplicationController Configurar arquivo /config/initializers/devise.rb # ==> Scopes configuration # Turn scoped views on. Before rendering "sessions/new", it will first check for # "users/sessions/new". It's turned off by default because it's slower if you # are using only default views. config.scoped_views = true
    • Devise @jlucasps user_signed_in? current_user user_session Métodos helpers gerados pelo Devise Caso o model seja Member before_filter :authenticate_member! member_signed_in? current_member member_session
    • Devise @jlucasps jlucasps@lotus:/media/truecrypt1/handsonrails/first_app$ rails generate devise:views users invoke Devise::Generators::SharedViewsGenerator create app/views/users/shared create app/views/users/shared/_links.erb invoke form_for create app/views/users/confirmations create app/views/users/confirmations/new.html.erb create app/views/users/passwords create app/views/users/passwords/edit.html.erb Customizar as views utilizadas pelo Devise
    • Devise @jlucasps class WelcomeController < ApplicationController before_filter :authenticate_user!, :except => [:index, :about, :contact] def index end def black render :layout => 'application_black' end def about end def contact end end Caso queira liberar acesso para actions do WelcomeController
    • Devise @jlucasps <div class="navbar navbar-inverse navbar-fixed-top"> <div class="navbar-inner"> <div class="container-fluid"> <button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <%= link_to "Project name", index_path, :class => "brand" %> <div class="nav-collapse collapse"> <p class="navbar-text pull-right"> <% if user_signed_in? %> Logged in as <%= link_to current_user.name edit_user_registration_path(current_user), : class => "navbar-link" %> <% else %> <%= link_to "login", new_user_session_path, :class => "btn" %> <% end %> </p> <ul class="nav"> <li class="active"><%= link_to "Home", index_path %></li> <li><%= link_to "About", about_path %></li> <li><%= link_to "Contact", contact_path %></li> </ul> </div><!--/.nav-collapse --> </div> </div> </div> Exibir link para login e usuário logado: /app/views/shared/_menu_top.html.erb
    • Devise @jlucasps <h2>Sign up</h2> <%= form_for(resource, :as => resource_name, :url => registration_path (resource_name)) do |f| %> <%= devise_error_messages! %> <div><%= f.label :name %><br /> <%= f.text_field :name, :autofocus => true %></div> <div><%= f.label :email %><br /> <%= f.email_field :email %></div> <div><%= f.label :password %><br /> <%= f.password_field :password %></div> <div><%= f.label :password_confirmation %><br /> <%= f.password_field :password_confirmation %></div> <div><%= f.submit "Sign up" %></div> <% end %> <%= render "users/shared/links" %> Alterar tela de cadastro de usuários: /app/views/users/registrations/new.html.erb
    • Devise @jlucasps RSpec.configure do |config| # ## Mock Framework # # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line: # # config.mock_with :mocha # config.mock_with :flexmock # config.mock_with :rr config.include Capybara::DSL config.include Devise::TestHelpers, :type => :controller config.include Rails.application.routes.url_helpers # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures #config.fixture_path = "#{::Rails.root}/spec/fixtures" Testes automatizados com Devise: /spec/spec_helper.rb
    • Devise @jlucasps include Warden::Test::Helpers def create_logged_in_user(user_sym) user = FactoryGirl.find_or_create(user_sym) login_as(user, scope: :user) user end class ActiveRecord::Base mattr_accessor :shared_connection @@shared_connection = nil def self.connection @@shared_connection || retrieve_connection end end ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection Devise support /spec/support/devise.rb
    • FactoryGirl @jlucasps # Factory_girl is a fixtures replacement with a straightforward definition syntax # https://github.com/thoughtbot/factory_girl_rails gem 'factory_girl_rails', "~> 4.0" Adicionar factory_girl ao Gemfile Importar factory_girl no spec_helper # This file is copied to spec/ when you run 'rails generate rspec:install' ENV["RAILS_ENV"] ||= 'test' require File.expand_path("../../config/environment", __FILE__) require 'rspec/rails' require 'rspec/autorun' require 'factory_girl' require 'factory_girl_patch' require 'capybara/rails' require 'capybara/rspec' FactoryGirl.register_strategy(:find_or_create, FactoryGirlPatch)
    • FactoryGirl @jlucasps FactoryGirl.define do factory :user_bart, :class => User do name "Bart Simpson" email "bart@simpson.com" password "dirty_boy" password_confirmation "dirty_boy" encrypted_password BCrypt::Password.create("dirty_boy", :cost => 10) end factory :user_lisa, :class => User do name "Lisa Simpson" email "lisa@simpson.com" password "smart_girl" password_confirmation "smart_girl" encrypted_password BCrypt::Password.create("smart_girl", :cost => 10) end end Criar factories
    • FactoryGirl @jlucasps class FactoryGirlPatch def association(runner) runner.run end def result(evaluation) evaluation.object.tap do |instance| evaluation.notify(:after_build, instance) evaluation.notify(:before_create, instance) saved_object = instance.class.where(instance.attributes.except("id", "created_at", "updated_at")).first if saved_object.present? instance.id = saved_object.id instance.created_at = saved_object.created_at if instance.respond_to?(:created_at) instance.updated_at = saved_object.updated_at if instance.respond_to?(:updated_at) else evaluation.create(instance) evaluation.notify(:after_create, instance) end end end end Estratégia find_or_create: /lib/factory_girl_patch.rb
    • Devise @jlucasps require 'spec_helper' describe UsersController do let(:user_bart) { FactoryGirl.find_or_create(:user_bart)} before(:each) do sign_in user_bart end describe "GET index" do it "assigns @users" do saved_users = [FactoryGirl.find_or_create(:user_bart), FactoryGirl.find_or_create(: user_lisa)] get :index assigns(:users).should eq(saved_users) end end end Testes no controller /spec/controllers/users_controller_spec.rb
    • Devise @jlucasps Testes no controller /spec/controllers/users_controller_spec.rb jlucasps@lotus:/media/first_app$ rspec spec/controllers/users_controller_spec.rb . Finished in 0.331 seconds 1 example, 0 failures Randomized with seed 5290
    • Desenvolvimento Web com Ruby on Rails João Lucas Pereira de Santana gtalk | linkedin | twitter: jlucasps Obrigado!