Devise login com modelos de usuário ou administrador e subdomínios de estilo Basecamp
-
26-09-2019 - |
Pergunta
Tenho modelos separados para criar usuários e administradores. Também estou usando subdomínios no estilo Basecamp. Tudo está funcionando bem, exceto para alguns controladores e ações em que eu preciso ser capaz de autenticar como usuário ou como administrador.
Atualmente eu tenho autenticate_user! Defina no meu Application_controller.rb e estou pulando com skip_before_filter para os controladores e ações que apenas os administradores devem ter acesso.
Infelizmente, não posso simplesmente especificar o requisito de autenticação em cada controlador, pois ainda precisarei de alguns controladores e ações para acesso por um usuário ou um administrador.
Eu tentei algumas coisas sem sucesso. Parece que se eu mover o autenticate_user! e autenticate_admin! Em algum tipo de lógica de detecção de subdomínio, ele falha em processar. Basicamente:
current_subdomain = request.subdomains.first
if current_subdomain == 'admin'
authenticate_admin!
else
authenticate_user!
end
Em um ponto, eu era capaz de tentar a autenticação, mas, por algum motivo, estava deixando de não ter a necessidade de autenticação, o que resultou em um loop de redirecionamento (um primeiro para mim com Ruby!).
Sei que poderia adicionar um campo ao meu usuário que denota o status do administrador, mas o aplicativo requer uma maior separação de poderes entre usuário e administrador do que isso permitirá, exceto por alguns controladores e ações.
- Ruby 1.9.2
- Rails 3.0.3
- Devise 1.1.3
Solução
Tente escrever o seu próprio antes do filtro ao longo das linhas de
#application_controller.rb
def authenticate_any!
if admin_signed_in?
true
else
authenticate_user!
end
end
Então, no controlador, onde você deseja que os administradores e o usuário possam ter acesso através do uso de autenticação
#myobject_controller.rb
before_filter :authenticate_any!
Se você fez login como administrador, passará o antes_filter, caso contrário, passará por autenticate_user! qual é o comportamento padrão.
Outras dicas
Na verdade, isso não funciona:
#application_controller.rb
def authenticate_any!
if admin_signed_in?
true
else
authenticate_user!
end
end
Iniciará uma recursão infinita no usuário autenticado.
tente isso em vez disso:
def authenticate_user!
return if admin_signed_in?
super
end
Lembre -se de que, com esta segunda solução, você está dizendo algo assim: 'Você deve estar conectado como, pelo menos, o usuário' e perderá apenas a autenticação dos usuários.
Os administradores poderão acessar tudo.
Talvez você deva considerar o Gem adicional - CanCan para lidar com papéis
Muito bom descrito aqui:http://www.tonyamoyal.com/2010/09/29/rails-authentication-with-devise-and-cancan-part-2-restful-resources-for-administradores/