contato@koshtech.com +55 21 98038-2606

Authlogic + CanCan no Rails 3: Autenticação e autorização de usuários - Parte 1

Você fez sua aplicação rails, mas espere aí: vai querer que só você acesse ela? Se você quiser que outras pessoas (usuários) tenham acesso a sua aplicação você vai precisar utilizar ferramentas de autenticação e autorização.

Você fez sua aplicação rails, mas espere aí: vai querer que só você acesse ela? Se você quiser que outras pessoas (usuários) tenham acesso a sua aplicação você vai precisar utilizar ferramentas de autenticação e autorização. Aqui estaremos em dois posts explicando como funciona o Authlogic e o CanCan. Antes uma breve explicação de o que é exatamente cada um deles. 
Authlogic
O Authlogic é uma solução de autenticação escrito em Ruby, mas diferente do Devise ele faz com que você realmente tenha que colocar a mão na massa e construir os models e controllers dos usuários e da sessão. Mas se você tem que fazer boa parte na mão porque utilizar ele? Uma das razões de utilizar o Authlogic é que ele gera tokens de autenticação da sessão, ou seja, apesar dele não gerar os controllers ele quem lida com toda a parte de autenticação em si, dando mais flexibilidade para a sua aplicação.
CanCan
O CanCan tem esse nome devido ao verbo can (poder) em inglês (The user can do this task/O usuário pode fazer esta tarefa). Basicamente o CanCan restringe os usuários atráves de regras (roles) dando ele acesso ou não a realizar determinadas tarefas.

Nesta primeira parte estaremos mostrando como configurar o Authlogic, deixaremos o CanCan para próxima parte. Vamos então para instalação do Authlogic.
Primeiro adicione dentro do seu arquivo Gemfile a seguinte linha:

gem 'authlogic', '>= 3.1.0'

Depois disso no seu shell rode o comando bundle.
Com isto a gem do authlogic já estará instalada, será necessário então criar o model e controller do usuário. Primeiro vamos criar o model, para isto rode o comando


rails g model User


    class CreateUsers < ActiveRecord::Migration

      def change

        create_table :users do |t|

          t.string :username

          t.string :email

          t.string :crypted_password

          t.string :password_salt

          t.string :persistence_token

          t.timestamps

        end

      end

    end

Os campos email, crypted_password, password_salt e persistence_token são reconhecidos automaticamente pelo Authlogic, portanto, ele sabe como lidar com estes campos e nós só precisamos adicionar eles.
Depois disto basta rodar a migração


rake db:migrate

O model gerado é um model padrão do rails, para funcionar com o authlogic, basta adicionar as seguintes linhas


    class User < ActiveRecord::Base

      attr_accessible :username, :email, :password, :password_confirmation

      acts_as_authentic

    end

Agora que o model está pronto, vamos gerar o controller para isto, basta rodar o seguinte comando no terminal


    rails g controller users new edit


    def new

      @user = User.new

    end

    def edit

      @user = current_user

    end

    def create

      @user = User.new(params[:user])

      if @user.save

        flash[:notice] = "Create successful!"

        redirect_to "/"

      else

        render :action => 'new'

      end

    end

    def update

      @user = current_user

      if @user.update_attributes params[:user]

        flash[:notice] = "Update successful!"

        redirect_to "/my_account"

      else

        render :action => :edit

      end

    end

Junto com o controller é criado também as views, pra elas funcionarem direitinho, nós as editamos para ficar assim:
users/_form.html.erb



    <%= form_for(@user) do |f| %>

      <% if @user.errors.any? %>

        ="error_explanation">

          <%= pluralize(@user.errors.count, "error") %> prohibited this user from being saved:

          

          <% @user.errors.full_messages.each do |msg| %>

            
  • <%= msg %>
     <% end %> </ul> </div> <% end %> <%= f.label :username %> <%= f.text_field :username %> </div> <%= f.label :email %> /> <%= f.text_field :email %> ="field"> <%= f.label :password %> <%= f.text_field :password %> </div> <%= f.label :password_confirmation %> /> <%= f.text_field :password_confirmation %> ="actions"> <%= f.submit %> <% end %>

users/new.html.erb


New user</h1>

    <%= render 'form' %>

    <%= link_to 'Back', users_path %>
users/edit.html.erb


Editing user</h1>

      <%= render 'form' %>

      <%= link_to 'Show', @user %> |

      <%= link_to 'Back', users_path %>

rails g model user_session

Depois disto é necessário editar o arquivo para que o modelo fique desta maneira:


    class UserSession < Authlogic::Session::Base

      def to_key

        new_record? ? nil : [ self.send(self.class.primary_key) ]

      end

      def persisted?

        false

      end

    end

Para que a sessão funcione plenamente é necessário fazer também um controller, fazemos com o comando


rails g controller UserSessions new

Depois como fizemos antes com o users, editamos o arquivo do controller para que ele fique assim:

    class UserSessionsController < ApplicationController

      def new

        @user_session = UserSession.new

      end

      

      def create

        @user_session = UserSession.new(params[:user_session])

        if @user_session.save

          flash[:notice] = "Login successful!"

          redirect_to '/posts'

        else

          flash[:notice] = "Login error!"

          render :action => :new

        end

      end

      def destroy

        @user_session = UserSession.find

        @user_session.destroy

        flash[:notice] = "Successfully logged out."

        redirect_to "/posts"

      end

    end

Aqui vemos que o método destroy serve para basicamente destruir a sessão do usuário, mas não é necessário pegar o id dela, o Authlogic faz a mágica de destruir de acordo com o usuário que está logado.
A view que é gerada é utilizada para fazer o login de fato do usuário, então editamos ela e deixamos ela assim
user_session/new.html.erb



    <% title "Log in" %>

    <% form_for @user_session do |form| %>

      <%= form.error_messages %>

      

      


  1.         <%= form.label :username, "Username" %>

            <%= form.text_field :username %>

          </li>

          


  2.         <%= form.label :password, "Password" %>

            <%= form.password_field :password %>

          

          
      3.
            <%= form.submit "Submit" %>

          


          

        <% end %>

Para finalizar a parte de logout da aplicação é necessário adicionar alguns métodos dentro do application_controller.rb conforme abaixo:


  class ApplicationController < ActionController::Base

      protect_from_forgery

      helper_method :current_user_session, :current_user

      before_filter :new_user_session

      private

      def current_user_session

        return @current_user_session if defined?(@current_user_session)

        @current_user_session = UserSession.find

      end

       

      def current_user

        return @current_user if defined?(@current_user)

        @current_user = current_user_session && current_user_session.record

      end

      def new_user_session

        @new_user_session = UserSession.new

      end

    end


Estes métodos que estamos adicionando servem para manipular a sessão do usuário o current_user_session pega a sessão do usuário que está logado no momento e a current_user pega o usuário que está logado. Isto faz com que o método current_user esteja disponível para utilizar nas views, como já foi feito antes nesse tutorial. Bom com isto terminamos a configuração básica do Authlogic, no próximo post veremos como fazer ele funcionar junto com o CanCan para realizar o permissionamento das áreas do seu projeto.