Implementando Login com Ruby on Rails (exemplo simples)
Bom, ja que fui criticado por “incentivar a utilização de JSF”, vou fazer mais alguns pequenos tutoriais de como implementar um login com outros frameworks, e este sim é para incentivar a utilização, ja que estou gostando bastante do Ruby On Rails
Antes de comparar os dois exemplos, lembre-se de que o Ruby On Rails te da uma estrutura pronta de aplicação, por tanto não vou precisar mostrar como configurar a base de uma aplicação como foi feito no outro exemplo …
Comecemos criando uma aplicação Ruby On Rails:
$rails nomeDaAplicação
Depois, vamos criar um controller para a autenticação:
$script/generate controller login login
Isto vai criar um controller de nome login, e uma view de nome login também.
O código do login_controller.rb vai ficar mais ou menos assim:
class LoginController < ApplicationController
def index
render :action => 'login'
end
def login
end
def do_login
username = params[:username]
password = params[:password]
if username.nil? || password.nil? || username==password
redirect_to :action => "login"
flash[:notice] = 'Usuário ou senha incorretos'
else
session["user_id"] = username
redirect_to :controller => "secure", :action => "index"
end
end
end
Basicamente o controller tem implementado apenas o método do_login, que vai fazer uma validação bem complexa, de o usuário e a senha terem sido fornecidos e não serem iguais, você pode adaptar isto a sua aplicação mais tarde …
A view de login, vai ficar assim:
<% form_tag :action => 'do_login' do %>
<table align="center" class="loginForm">
<tr>
<td>
<%= image_tag "botao_login.png" %>
</td>
<td>
<input type="text" name="username"/>
</td>
</tr>
<tr>
<td>
<%= image_tag "botao_senha.png" %>
</td>
<td>
<input type="password" name="password" />
</td>
</tr>
<tr>
<td colspan="2">
<%= image_submit_tag "box_avancar.png", :style => 'width:75px;height:25px;' %>
</td>
</tr>
<table>
<% end %>
É uma view simples, apenas com um formulário e dois campos …
Ok, beleza, e como é que eu uso isto?
Vamos começar alterando application.rb, o código vai ficar assim:
class ApplicationController < ActionController::Base
# Pick a unique cookie name to distinguish our session data from others'
session :session_key => '_untitled6_session_id'
before_filter :authorize
protected
# Override in controller classes that should require authentication
def secure?
false
end
private
def authorize
if secure? && session["user_id"].nil?
session["return_to"] = request.request_uri
redirect_to :controller => "login", :action => "login"
return false
end
end
end
O que fizemos foi adicionar um filter a todos os métodos de todos os controllers, que vai interceptar a chamada a todos os métodos, e por padrão não vai fazer nada (o método secure? retorna false por padrão), caso o controller sobreescreva este método e faça-o retornar true, o filtro vai verificar se existe um user_id na sessão, se existir segue o processamento normal, caso contrário redireciona para o login.
E como utilizamos isto? vamos fazer um exemplo de um controller que vai precisar de segurança …
$script/generate controller seguro index
Para gerar um controller de nome seguro, e com uma ação de nome index.
Agora vamos alterar o código do securo_controller.rb
class SeguroController < ApplicationController
def index
end
protected
def secure?
true
end
end
Sobre escrevendo o método secure? para retornar true, fizemos com que todos os métodos deste controller precisem de autenticação para permitir o acesso.
E se quisermos que apenas alguns métodos precisem de autenticação?
Podemos utilizar algo parecido com este código:
protected
def secure?
["metodoSegro","outroMetodoSeguro"].include?(action_name)
end
Tudo pronto, login implementado …
Mas como no exemplo com JSF, ainda podemos melhorar esta implementação, por exemplo, armazenando na sessão os grupos do usuário para poder fazer uma melhor verificação dentro dos métodos …
Outra possível melhoria, seria aproveitar o atributo: session["return_to"] dentro do método do_login para redirecionar o usuário para a URL que ele tentou acessar originalmente ...
E como no último post, deixo algumas perguntas para vocês:
- Quais outras possíveis melhorias vocês vêem neste exemplo?
- Quais problemas vocês vêem nesta implementação?
Para quem estiver interessado em mais detalhes sobre Ruby On Rails, podem dar uma olhada no tutorial que eu traduzi:
Quatro dias de Ruby On Rails - Primeiro dia, Quatro dias de Ruby On Rails - Segundo dia,
Quatro dias de Ruby On Rails - Terceiro Dia, Quatro dias de Ruby On Rails - Quarto Dia
A próxima implementação de login, acho que vai ser com o Wicket, até para eu aprender um pouco sobre ele
(seufagner, não se anima a escrever este para postar aqui?)
Se você gostou deste post, lembre-se de assinar o RSS feed do blog, para ser notificado de novos posts!



session[”user_id”]
session[”return_to”]
Você pode (deve?) usar símbolos session[:user_id] e session[:return_to] ao invéz de string.
Além disso, já que você salvou a URL original, como você comentou, poderia ter utilizado abaixo para redirecionar ;P
Eu geralmente utilizo o “skip_before_filter” nos controladores onde alguma action não precisa de autênticação ao invéz de colocar esse método “secure?”, mas isso não faz muita diferença
dos simbolos eu sei que posso utilizar, utilizo na maior parte dos casos
não sei por que não utilizei no exemplo …
Eu não salvei utilizei a URL por que copiei o exemplo de um sistema que estou desenvolvendo, e naquele sistema só tem uma situação que eu realmente preciso disto, na maior parte dos casos isto me causaria problemas, então deixei como exercicio, como comentei no final, que isto poderia ser melhorado
e valeu a dica do skip_before_filter, eu não sabia dele

acho que fica mais “polido” do que o “secure?” mesmo
Belo Post Urubatan… acho que logo logo alguem vai estar suando RoR na maioria de seus projetos hehehe
A outra melhoria seria usar o plugin do gem
http://wiki.rubyonrails.com/rails/pages/Acts_as_authenticated
Verdade Maximiliano, isto seria mais fácil e mais produtivo


mas a idéia deste post era apresentar a base do funcionamento
Inclusive o act_as_authenticated trabalha com conceitos bem parecidos
Eu to escrevendo um post sobre Wicket e vou usar um sisteminha de login para mostrar alguns conceitos dele… Boa sugestao
[…] Assim como JSF, Tapestry e ASP.NET, o Wicket é um framework […]
[…] Implementando Login com Ruby on Rails (exemplo simples) […]
Gostei mesmo, como essas iniciativas a linguagem começa a crescer.