Membuat sistem keanggotaan Web (Membership)

Di dalam suatu aplikasi web, pada umumnya terdapat sistem keanggotaan, dimana user yang menjadi anggota dapat memiliki kelebihan-kelebihan tertentu misalnya bila owner / pemilik dari web dapat mengendalikan seluruh isi web, bila admin bisa mengantur keanggotaan dari user yang lain, atau bisa juga bila seseorang menjadi member dari suatu web dapat melihat data-data khusus yang tidak bisa dilihat oleh user yang "non member", maka pada bagian ini akan dijelaskan proses pembuatannya

Membuat sistem keanggotaan Web (Membership)

Mempersiapkan session dan mengatur hyperlink (routing)

  • Pada langkah berikut, kita akan membuat session saat user melakukan login
  • dan nantinya pada saat user melakukan logout kita akan menghapus file session
  • jalankan command prompt for ruby dan ketik perintah berikut:
  cd intomyidea
  rails generate controller sessions new
  • Dengan menggunakan sublime, pilih menu file, open folder
    • arahkan ke c:\sites\intomyidea
  • buka file berikut /config/routes.rb
    • hapus isi yang ada
    • lakukan copy - paste dari ketikan berikut:
Rails.application.routes.draw do

  # root artinya halaman utama
  # bila user mengetik www.intomyidea.com
  # maka akan keluar halaman root
  root to: 'users#index'

  # for object users
  resources :users

  # dibuat untuk user login
  # get "sessions/new"
  resources :sessions, only: [:new, :create]

  # dibuat untuk matching
  match '/register', to: 'users#new', via: :get
  match '/login'   , to: 'sessions#new', via: :get
  match '/logout'  , to: 'sessions#destroy', via: :delete
  match '/account' , to: 'users#show', via: :get
end

Berikut penjelasan dari perintah diatas.

  • root to: artinya bila user mengetik nama domain misalnya www.intomyidea.com akan ditampilkan data dari model users
  • resources :users berarti untuk model user 7 standard controller akan digunakan semua
    • ingat 7 standard itu adalah new, create, edit, update, index, show, destroy
  • Perintah resources :sessions, only: [:new, :create]
    • artinya bila kita mengetikkan resources :sessions berarti untuk session kita akan menggunakan 7 buah standard controller, tetapi karena kita mengikut sertakan kata-kata only berarti kita hanya akan menggunakan 2 buah link saja yaitu new, yang digunakan saat user melakukan klik tombol login dan create yang digunakan saat user melakukan klik tombol submit setelah selesai mengetikkan username dan passwordnya
  • Perintah match diatas juga untuk membuat 3 buah link baru

Mengatur session dengan controller

  • Buka file /controllers/sessions_controller.rb
    • hapus seluruh isinya dan lakukan copy - paste pada ketikan dibawah ini
class SessionsController < ApplicationController
  def new

  end

  def create
    user = User.find_by_username(params[:session][:username])
    if user && user.authenticate(params[:session][:password])
        login user
        flash[:success] = "Anda berhasil login"
    else
        flash.now[:error] = 'Maaf proses login tidak berhasil'
        render 'new'
    end
  end

  def destroy
    session[:user_id] = nil
    flash[:success] = "Anda berhasil Log Out"
    redirect_to root_url
  end
end
  • pada proses diatas params[:session][:username] diambil dari web
  • saat user klik pada tombol submit
  • lalu di proses di create kemudian namanya di search by_username
  • bila ketemu maka kan masuk ke variabel tipe record user
  • karena di Gemfile kita include bcrypt maka variabel user
  • punya method authenticate dan inputnya adalah passwordnya user
  • dari form
  • bila keduanya true maka panggil method login dengan parameter user
  • sebenarnya cara tulisnya adalah login(user) tapi karena di ruby
  • tanda kurung boleh tidak ditulis
  • bila berhasil masuk keluarkan message dan ke home
  • bila tidak maka supaya keluar message hanya 1x saja maka ditulis
  • flash.now kemudian di render kembali new supaya bisa kelihatan
  • errornya

membuat program tambahan di application controller

  • Beberapa modul program tidak bisa ditempatkan di satu tempat saja misalnya di dalam file session controller saja, karena program tersebut tidak bisa dipanggil oleh program lain misalnya untuk mengecek seorang user sekarang ini sudah login atau belum (current_user) , modul program ini dibutuhkan di banyak tempat
  • bila suatu bagian program (def) dibutuhkan di banyak model (user dan nantinya idea), maka tempat yang tepat adalah di lokasi /app/controllers/application_controller.rb
  • karena itu buka file /app/controller/application_controller.rb
    • hapus isinya dan lakukan copy - paste dari program berikut:
class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception

  helper_method [:current_user, :logged_in?, :auth, :avatar_url]

  rescue_from ActiveRecord::RecordNotFound do | exception |
    flash[:error] = "Maaf data tidak ditemukan"
    redirect_to root_path
  end

  def avatar_url(user,size=48)
  # method to get image from gravatar.com
      default_url = "mm"
      gravatar_id = Digest::MD5.hexdigest(user.email.downcase)

      "http://gravatar.com/avatar/#{gravatar_id}.png?s=#{size}&d=#{CGI.escape(default_url)}"
  end

  protected

  def current_user
    current_user ||= User.find(session[:user_id]) if session[:user_id]
  end

  def logged_in?
    !current_user.nil?
  end

  def login(user)
    session[:user_id] = user.id
    flash[:success] = "Anda berhasil login"
    redirect_to :controller => "users", :action => "show", :id => user.id
  end

  def auth
    redirect_to login_url, alert: 'Maaf anda harus login' unless logged_in?
  end

end
  • berikut penjelasan satu-persatu untuk setiap bagian program diatas.
  • perlu saya informasikan terlebih dahulu bahwa suatu blok perintah yang diawali dengan def ..... sampai diakhir end didalam ruby disebut method
  • pada contoh diatas berarti ada method avatar_url, current_user, login , dan seterusnya
  • protect_from_forgery with: :exception
    • setiap aplikasi rails yang dibuat sudah menyertakan baris ini
    • gunanya adalah untuk menghindari serangan hacker pada web yang kita buat.
  • helper_method [:current_user, :logged_in?, :auth, :avatar_url]
    • bila suatu method nantinya akan digunakan di dalam suatu view maka hendaknya method tersebut dituliskan di bagian helper_method
    • contoh paling mudah adalah avatar_url dimana avatar_url ini methodnya akan dipanggil untuk menampilkan foto profile dari user yang sedang login, method ini digunakan di 2 tempat yaitu di bagian untuk menampilkan menu diatas dan saat nanti user melihat profilenya sendiri
    • bila suatu method hanya digunakan di controller dan tidak ada hubungan dengan tampilan program (view) maka tidak perlu dituliskan di bagian helper method.
  • rescue_from ActiveRecord::RecordNotFound artinya bila ada data yang dicari misalnya mencari data user yang usernamenya tidak ada maka akan dikeluarkan pesan maaf data tidak ditemukan
  • method avatar_url
    • digunakan untuk menampilkan foto dari user profile
    • user harus mendaftarkan emailnya terlebih dahulu di website gravatar.com, jadi nanti data fotonya diambil dari web gravatar.com dan ditampilkan di web yang kita buat.
  • method login(user)
    • saat user memasukkan username dan password dengan benar maka method ini dipanggil
    • dan kita mengisi variabel session[:user_id] dengan id dari user
    • kemudian perintah redirect_to artinya halaman web user diarahkan ke profile dari user dengan memanggil controller user, method show, dan id-nya diberikan id milik user yang baru saja login.
  • current_user berfungsi mengetahui user siapa yang sedang login saat ini
    • artinya bila session[:user_id] ada isinya misalnya 3, maka komputer akan mencarikan detil data user tersebut dengan cara melakukan search pada tabel user dengan perintah User.find(session[:user_id]), bila berhasil ditemukan maka akan dimasukkan ke variabel current_user, sehingga bila kita nantinya ingin tahu dari nama user yang sedang login kita dapat mengetik current_user.username, bila kita ingin tahu role dari user tersebut maka kita dapat mengecek dengan perintah current_user.role
  • logged_in? berfungsi untuk memeriksa apakah apakah user yang sedang membuka website ini sudah login atau belum, cara mengeceknya adalah melalui variabel current_user, bila current_user tidak ada isinya alias nil, berarti user yang saat ini sedang menggunakan web belum login.

membuat proses dan login

  • buka file app/views/sessions/new.html.erb
  • lakukan copy - paste pada ketikan berikut:
<% provide( :title, 'Login') %>
<div class="row">
  <div class="col-md-4 col-md-offset-4" >
    <%= form_for(:session, url: sessions_path) do |f| %>
      <div class="panel panel-primary">

        <div class="panel-heading text-center">
          <h5 class="text-uppercase">
            <strong>Login</strong>
          </h5>
        </div>

        <div class="panel-body">
          <%= f.label :username, "User name"%>
          <div class="input-group">
            <span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
            <%= f.text_field :username, class: "form-control input-lg", placeholder: "user name" %>
          </div>

          <%= f.label :password, "Password" %>
          <div class="input-group">
            <span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
            <%= f.password_field :password, class: "form-control input-lg", placeholder: "password"  %>
          </div>
          <p></p>
          <div class="text-center">
            <div class="login-btn">
              <%= f.submit "Log in", class: "btn btn-ui btn-lg btn-block" %>
            </div>
          </div>
        </div>
      </div>
    <% end %>
  </div>
</div>

membuat hyperlink untuk proses register, login dan logout

  • dengan sublime, buka File, app/views/layouts/application.html.erb
    • lakukan copy - paste dari ketikan dibawah ini
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

  <title><%= yield(:title) %></title>
  <%= stylesheet_link_tag    "application", media: "all", "data-turbolinks-track" => true %>
  <%= javascript_include_tag "application", "data-turbolinks-track" => true %>
  <%= csrf_meta_tags %>
  </head>

  <body>
    <div id="header" class="navbar navbar-fixed-top navbar-default" role="navigation">
      <div class="container-fluid">
        <!-- menu for mobile -->
        <div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-megadropdown-tabs">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="#">INTO MY IDEA</a>
        </div>

        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class="collapse navbar-collapse" id="bs-megadropdown-tabs">
          <!-- navbar for left menu 
            <ul class="nav navbar-nav">
              <li><a href="#">Menu 1</a></li>
              <li><a href="#">Menu 2</a></li>
          </ul> -->

          <ul class="nav navbar-nav navbar-right">
              <li><%= link_to "IDEA",    root_path %></li>
              <li><%= link_to "HELP",    "" %></li>
              <li><%= link_to "CONTACT",    "" %></li>
              <% if logged_in? %>
                <li class="dropdown">
                  <a href="#" data-toggle="dropdown" class="dropdown-toggle">MENU <b class="caret"></b></a>
                    <ul class="dropdown-menu">
                        <li class="divider"></li>
                          <li><%= link_to "Change Password", edit_user_path(current_user) %></li>
                    </ul>
                </li>
                <li> <%= link_to "LOG OUT ( #{current_user.username} )", logout_path, method: 'delete' %></li>
                <li><%= image_tag avatar_url(current_user), class: "ratio img-responsive img-circle"  %></li>
               <% else %>
                <li><%= link_to "REGISTER", register_path %></li>
                <li><%= link_to "LOGIN", login_path %></li>
              <% end %> 
          </ul> <!-- navbar-right  -->
        </div><!-- end navbar-collapse -->
      </div> <!-- end fluid -->
    </div> <!-- end navbar -->

    <!-- Content web -->
    <div id="content" class="container">
      <% flash.each do |key, value| %> <!-- start flash message... -->
        <div class="alert alert-<%= key == "success" ? "success" : "danger"  %>">
          <%= value %>
        </div>
      <% end %> <!-- end flash message -->

      <%= yield %>

    </div><!-- end Content -->

    <!-- footer
    <div id="footer" class="text-center navbar navbar-inner navbar-fixed-bottom">
      &copy; kelasdigital.com <%= Date.today.year %>
    </div>
    -->

  </body>
</html>

Testing Register, login dan logout

  • klik start, ketik command , klik command prompt with ruby
  • cd intomyidea
  • jalankan servernya dengan mengetik rails server
  • buka browser dan ketik localhost:3000
  • Klik pada link register, cobalah melakukan register 1 user baru
  • setelah sukses mendaftarkan 1 user baru, cobalah klik pada tombol login
    • lakukan login dengan username dan password yang salah dulu
    • lakukan login dengan username dan password yang benar
  • bila berhasil login, klik pada menu logout