Solucionado (ver solução)
Solucionado
(ver solução)
15
respostas

Sistema deslogando sozinho apos qualquer ação

Atualmente estou com o seguinte problema no meu sistema de Login/Autorizador. Ele esta fazendo Login, porem qualquer ação executada, desloga o usuário do sistema.

Exemplo: Logar -> CTRL + F5 = desloga o usuario do sistema, ou acessar outra pagina, tambem desloga o usuario do sistema.

LoginBean:

@ManagedBean(name = "LoginMB")
@ViewScoped
public class LoginBean {

    private Pessoa pessoa = new Pessoa();
    private PessoaDAO pessoaDAO = new PessoaDAO();
    private TimeBean timeBean;

    // Metodo para efetuar login na aplicação
    public String efetuaLogin() {

        // Vai imprimir no console o nome do usuario logado
        System.out.println("Fazendo login do usuário " + this.pessoa.getNomeUsuario());

        // facesContext e utilizado para pegar o nome da pagina
        FacesContext context = FacesContext.getCurrentInstance();
        boolean existe = new PessoaDAO().existe(this.pessoa);

        if (existe) {

            // Se usuario existir, armazena o usuario em usuarioLogado e mantem na sessão
            // Depois redireciona para a pagina seguinte

            context.getExternalContext().getSessionMap().put("usuarioLogado", this.pessoa);
            return "cadastrarTime?faces-redirect=true";
        }

        // Caso não exista, exibe a mensagem
        // Redireciona o usuario paga a pagina seguinte

        context.getExternalContext().getFlash().setKeepMessages(true);
        context.addMessage(null, new FacesMessage("Usuário não encontrado"));
        return "login?faces-redirect=true";
    }

    public String deslogar() {

        // Metodo para deslogar o usuario
        // Remove o usuariologado da SessionMap


        FacesContext context = FacesContext.getCurrentInstance();        
        context.getExternalContext().getSessionMap().remove("usuarioLogado");


        // Depois de remover ele e redirecionado para a pagina seguinte

        return "login.xhtml";        
    }

Login.xhtml:

<h:form>
                                <div class="form-group input-icon-left">
                                    <i class="fa fa-user"></i>
                                    <h:inputText type="text" placeholder="Usuário"
                                        class="form-control" name="Usuário"
                                        value="#{LoginMB.pessoa.nomeUsuario}" />
                                </div>
                                <div class="form-group input-icon-left">
                                    <i class="fa fa-lock"></i>
                                    <h:inputSecret value="#{LoginMB.pessoa.senhaUsuario}"
                                        class="form-control" name="Senha" placeholder="Senha" />

                                </div>


                                <h:commandButton value="Login" action="#{LoginMB.efetuaLogin}"
                                    class="btn btn-primary btn-block" />

                                <div class="form-actions">
                                    <div class="checkbox checkbox-primary">
                                        <input type="checkbox" id="checkbox" /> <label for="checkbox">Lembrar-me</label>
                                    </div>
                                </div>
                            </h:form>
15 respostas

Oi Rafael,

vc tbm implementou o interceptador?

abs

Oi Rafael,

Qual o local da sua aplicação onde vc verifica se o usuário está logado? Deve ter algum lugar que vc faz essa verificação e aí da permissão para ele continuar a navegação.

Verifique se o bean está com o escopo correto. Se ele estiver como RequestScopped depois do login o bean morre e perde as informações.

E o interceptador?

Vamos la pessoal, desculpe a demora.

Alberto Souza:

Utilizo a classe Autorizador, como no projeto do curso mesmo.

Autorizador:

ublic class Autorizador implements PhaseListener {

private static final long serialVersionUID = 1L;

// PhaseListener e um recurso do JSF que filtra as requisições @Override public void afterPhase(PhaseEvent event) {

// o getViewRoot e usado paga pegar o nome da pagina pelo metodo // getViewId FacesContext context = event.getFacesContext(); String nomePagina = context.getViewRoot().getViewId();

// Imprimi o nome da pagina System.out.println(nomePagina);

// Não queremos bloquear a pagina loginnem cadastrarUsuario, porque o usuario precisa dela // para fazer a autenticação e acessar as demais paginas if ("/login.xhtml".equals(nomePagina)|| "/cadastrarUsuario.xhtml".equals(nomePagina)) { // O return significa que não vamos fazer nada return; }

// Vamos verificar se realmente o usuario esta logado Pessoa usuarioLogado = (Pessoa) context.getExternalContext().getSessionMap().get("usuarioLogado");

// Se ele for diferente de nullo, então ele esta logado if (usuarioLogado != null) { return; }

// Se chegar a essa parte do código, significa que o usuario não esta // logado, portanto ele devera ser redirecionado a pagina de Login NavigationHandler handler = context.getApplication().getNavigationHandler(); handler.handleNavigation(context, null, "/login?faces-redirect=true");

context.renderResponse(); }

@Override public void beforePhase(PhaseEvent event) { }

@Override public PhaseId getPhaseId() { return PhaseId.RESTORE_VIEW; } }

PhaseListener:

public class LogPhaseListener implements PhaseListener {

private static final long serialVersionUID = 1L;

@Override public void afterPhase(PhaseEvent arg0) { }

@Override public void beforePhase(PhaseEvent event) { System.out.println("FASE: " + event.getPhaseId()); }

@Override public PhaseId getPhaseId() { return PhaseId.ANY_PHASE; }

}

Alberto Souza, fiz de acordo com o projeto proposto pelas aulas do curso.

Verifico pela classe Autorizador.

Marcio Shibao, todas as minhas beans estão com o @SessionScoped

Inclusive a LoginBean:

@ManagedBean(name = "LoginMB")
@ViewScoped
public class LoginBean {

    private Pessoa pessoa = new Pessoa();
    private PessoaDAO pessoaDAO = new PessoaDAO();
    private TimeBean timeBean;

    // Metodo para efetuar login na aplicação
    public String efetuaLogin() {

        // Vai imprimir no console o nome do usuario logado
        System.out.println("Fazendo login do usuário " + this.pessoa.getNomeUsuario());

        // facesContext e utilizado para pegar o nome da pagina
        FacesContext context = FacesContext.getCurrentInstance();
        boolean existe = new PessoaDAO().existe(this.pessoa);

        if (existe) {

            // Se usuario existir, armazena o usuario em usuarioLogado e mantem na sessão
            // Depois redireciona para a pagina seguinte

            context.getExternalContext().getSessionMap().put("usuarioLogado", this.pessoa);
            return "cadastrarTime?faces-redirect=true";
        }

        // Caso não exista, exibe a mensagem
        // Redireciona o usuario paga a pagina seguinte

        context.getExternalContext().getFlash().setKeepMessages(true);
        context.addMessage(null, new FacesMessage("Usuário não encontrado"));
        return "login?faces-redirect=true";
    }

    public String deslogar() {

        // Metodo para deslogar o usuario
        // Remove o usuariologado da SessionMap


        FacesContext context = FacesContext.getCurrentInstance();        
        context.getExternalContext().getSessionMap().remove("usuarioLogado");


        // Depois de remover ele e redirecionado para a pagina seguinte

        return "login.xhtml";        
    }

    public Pessoa getPessoa() {
        return pessoa;
    }

    public void setPessoa(Pessoa pessoa) {
        this.pessoa = pessoa;
    }

    public PessoaDAO getPessoaDAO() {
        return pessoaDAO;
    }

    public void setPessoaDAO(PessoaDAO pessoaDAO) {
        this.pessoaDAO = pessoaDAO;
    }

    public TimeBean getTimeBean() {
        return timeBean;
    }

    public void setTimeBean(TimeBean timeBean) {
        this.timeBean = timeBean;
    }


}

Pessoal, acabei de notar que isso começou a acontecer depois que implementei uma condição em um menu no template.

A condição e o seguinte:

<div class="nav-right">
            <div class="nav-profile dropdown">
                <a href="#" class="dropdown-toggle" data-toggle="dropdown"> <img
                    src="prototipo/img/user/avatar.jpg" alt="" /> <h:outputText
                         value="#{TimeMB.usuarioLogado().nomeUsuario != null ? TimeMB.usuarioLogado().nomeUsuario :  'Faça o login'}" /></a> 

                <c:if test="#{TimeMB.usuarioLogado() != null}">
                    <ul class="dropdown-menu">
                        <li><a href="perfil.xhtml"><i class="fa fa-user"></i>
                                Profile</a></li>
                        <li><a href="#"><i class="fa fa-heart"></i> Likes <span
                                class="label label-info">32</span></a></li>
                        <li><a href="#"><i class="fa fa-gamepad"></i> Games</a></li>
                        <li><a href="#"><i class="fa fa-gear"></i> Settings</a></li>
                        <li class="divider"></li>
                        <li><a href="#{LoginMB.deslogar()}"><i class="fa fa-power-off"></i>
                                Sign Out</a></li>
                    </ul>
                </c:if>
            </div>

Estou falando desse

<a href="#{LoginMB.deslogar()}"><i class="fa fa-power-off"></i>
                                Sign Out</a>

Se eu remover isso, ele volta a funcionar normalmente.

Segue o método deslogar do LoginMB:

public String deslogar() {

        // Metodo para deslogar o usuario
        // Remove o usuariologado da SessionMap


        FacesContext context = FacesContext.getCurrentInstance();        
        context.getExternalContext().getSessionMap().remove("usuarioLogado");


        // Depois de remover ele e redirecionado para a pagina seguinte

        return "login.xhtml";        
    }

O ideal nesse caso era ter usado um commandlink, o a href não funciona em jsf. Por exemplo.

//JSF
<h:link value="Login page" outcome="login" />

//HTML output
<a href="/JavaServerFaces/faces/login.xhtml">Login page</a>

Desculpe Marcio, usar o h:link no return do método deslogar ?

return "login.xhtml";

Ou no menu ?

<li><a href="#{LoginMB.deslogar()}"><i class="fa fa-power-off"></i>
                                Sign Out</a></li>
solução!

no xhtml não podemos utilizar a tag . Por isso precisa trocar a tag entao em vez de

<li><a href="#{LoginMB.deslogar()}"><i class="fa fa-power-off"></i> Sign Out</a></li>

ficaria algo parecido com isso.

<li><h:commandLink action="#{loginMB.deslogar()}" value="Sign Out" styleClass="fa fa-power-off"/></li>

Resolveu Marcio, porem tive que colocar dentro de um h:form, teria outra forma de fazer isso ?

Não, em geral quase tudo que precisa ser clicklado precisa estar dentro de um form. Se não ele não sabe como transformar a action. No fundo o xhtml vai ser transformado em html e o action fica no form, por isso precisa estar em <h:form

Obrigado a todos que me ajudaram, agora so vou trabalhar no template do h:form