Solucionado (ver solução)

Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

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