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

Logout Personalizado / Modificar o código ao fazer logout

Olá, minha dúvida é a seguinte: Após terminar a aula de login/logout vi que após fazer um logout, ele meio que volta para a tela de login novamente, certo? Então, só que ao meu ver isso não é tão adequado, deveria voltar para a outra página. então fui em busca do logout personalizado e como faze-lo e até consegui, mas tem algumas questões. Procurando muito eu achei que deveria ser implementado um contrato para realizar essa função e fiz. Descobri como fazer o redirect através do método sendRedirect e aí que vi deveria colocar a URL e resolvi colocar ela completa e funcionou como esperado, nesse caso ele ta redirecionando corretamente para produtos. Mas por exemplo, tem que colocar ela completa desse jeito ou tem um jeito melhor? Digo isso porque eu tentei fazer com redirect:/produtos e não funcionou igual a colocar a URL completa, ele funcionou diferente. Simplesmente o que ele ta fazendo é o logout e após isso ele meio que volta para a página anterior ao logout e isso é algo que eu realmente gostaria de aprender, e com isso eu consigo mas esse acho que não seria o melhor jeito de fazer, acredito que deva ser uma gambiarra. Então como eu poderia fazer isso? Cheguei a tentar dando um get na URL através daqueles objetos do método logout mas a URL não resulta na URL anterior que eu estava antes(Método esse que está listado ali embaixo) que resulta na URL de logout . Minhas dúvidas são mais essas duas mesmos: 1 - Eu preciso colocar a URL completa? Teria outro jeito de fazer ali? 2 - Como eu poderia após o logout retornar a URL que estava antes? (Porque eu acredito que é algo fixo, se existem duas páginas com botão sair, ao clicar nele provavelmente vai redirecionar a mesma página, mas como eu poderia após clicar no botão sair ele simplesmente manter a página anterior que já estava? Ou eu estou enganado nisso que estou afirmando?

Segue abaixo como está o código que implementa o contrato:

public class LogoutHandler implements org.springframework.security.web.authentication.logout.LogoutHandler {

    @Override
    public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
        System.out.println("Consegui, agora é só redirecionar para a página desejada...");
        try {
                response.sendRedirect("http://localhost:8080/casadocodigo/produtos");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

Método usado para tentativa de após logout redirecionar a página anterior que estava antes:

                System.out.println(request.getRequestURL().toString());

A URL mostrada no console foi: http://localhost:8080/casadocodigo/logout que não é a que eu quero.

7 respostas
solução!

Olá João Ferreira, tudo bem? Peço desculpas pela demora no retorno! Acho que tu isso poderia ser feito de uma forma melhor, se utilizando do authorizeRequests, no caso no método configure da classe SecurityConfiguration, você poderia modificar as linhas:

.and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                .permitAll().logoutSuccessUrl("/login");

E indicar outra pagina ou rota para quando o logout tenha sido efetuado com sucesso. Isso não resolver seu problema?

Espero ter ajudado e fala pra gente qualquer coisa a respeito!

Entendo, eu acabei marcando como solução sem querer mas ainda persiste algumas coisas, acho que teria abrir outro tópico mesmo. Obrigado, desse jeito aí já foi bem mais fácil, apenas coloquei nesse código que você disse a / e já redireciona para a página principal. Mas eu observei algumas coisas, colocando naquele meu código do handler que passei acima: Ao colocar somente / ele não encontra a URL, mas colocando redirect:/ ele redireciona para a página principal corretamente mas aquele botão "sair" não some(Tem código que o esconde para que quem não tiver logado não o veja), só some se eu der F5. Deve ter a ver com ser redirect.

Outra coisa seria ao deslogar manter a página anterior. Exemplo: Estou em um produto e ao clicar em sair ele deslogar a voltar para a página anterior que eu estava antes de clicar no botão, mas não sei como faria isso e mesmo que fosse possível acho que em uma página real isso não deve ser muito utilizado? Pois eu vi em um site por exemplo que sempre quando se desloga é redirecionado para a home.

João, não consigo ti falar o problema com o botão sair sem ver todo o código, e provavelmente tem a ver com o redirect mesmo. Já sobre a página que vai ser acessada após o logout, você poderia deixar configurado da seguinte forma:

.and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                .permitAll().logoutSuccessUrl("/home");

Claro que a sua página home precisa está liberada.

Espero ter ajudado!

Bom pelo que vi ali eu teria que alterar para a página /home no controller não é? Mas de qualquer forma como eu disse ali em cima eu já consegui do jeito que você propôs, ele dá certo sim. Só coloquei / nesse último código que você passou e ele já redireciona para a página principal. Acontece que talvez eu precise desse handler para poder retornar a página anterior ao invés de uma fixa.

Mas de qualquer forma o código do botão de sair está no cabeçalho.jsp ele é esse daqui:

<security:authorize access="isAuthenticated()">
                            <li><a href="<c:url value="/logout" />" rel="nofollow">Sair</a></li>
                        </security:authorize>

Mas após realizar o logout, o botão não some, como se o usuário ai ainda estivesse logado, só irá sumir se eu der o refresh na página.

O código desse handler é o seguinte:

public class LogoutHandler implements org.springframework.security.web.authentication.logout.LogoutHandler {

    @Override
    public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
        System.out.println("Consegui, agora é só redirecionar para a página desejada...");
        try {
                response.sendRedirect("redirect:/");
                System.out.println(request.getRequestURL().toString());
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

Entendi João Ferreira, só o que me passa pela cabeça que esteja dando problema seja essa linha:

<security:authorize access="isAuthenticated()">

Você fez o import dessa tag security corretamente? Outra coisa, você fez sua própria classe para fazer o Logout e isso pode ser o problema, talvez o spring não esteja conseguindo verificar o método isAuthenticated().

Bom, quando você mencionou import eu me lembrei de contrato e resolvi implementar um outro parecido que exercia a mesma função e mesmo assim não deu certo. Foi ai que bati o olho no nome do método e depois vi a documentação , e percebi que ele já faz o redirect, não precisa da palavra redirect ali no parâmetro. Também percebi que o logout era feito da forma correta mas não acontecia redirect nenhum. Tanto que se por exemplo seu tivesse na página de listagem de produtos e fizesse o logout ele permanecia lá. Mas como eu disse mais acima só colocar / na bastava, não encontrava certo e o problema era o contexto. Eu resolvi o problema utilizando ele através do seguinte código:

@Override
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
            throws IOException, ServletException {

        try {
            response.sendRedirect(response.encodeRedirectURL(request.getContextPath() + "/"));

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

Pronto, agora foi resolvido, obrigado pela atenção aí, valeu mesmo!

Que legal que conseguiu resolver João! Fico muito feliz por ajudar! Continue assim e bons estudos!