-1

The problem is that i'm calling a POST request to '/logout' but the browser logs a GET request

    import React from 'react';
    import axios from "axios";
    import { useState } from 'react';

    function Logout() {
        const [userIsLoggedIn, setUserIsLoggedIn] = useState(false);

        const handleLogout = async () => {
            try {
                // Make a request to your backend logout endpoint
                await axios.post('http://localhost:8080/logout'); // Update the endpoint URL accordingly

                // Remove the JWT token from localStorage
                localStorage.removeItem('jwtToken');

                // Update the userIsLoggedIn state to false
                setUserIsLoggedIn(false);
            } catch (error) {
                console.error('Error during logout:', error);
            }
        };

        return (
            <div>
                <button onClick={handleLogout}>Log uit</button>
            </div>
        );
    }

    export default Logout;

I'm trying to use the Spring Security default '/logout' functionality

package com.example.solarproject.config;


import com.example.solarproject.filter.JwtRequestFilter;
import com.example.solarproject.service.CustomUserDetailsService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;


@Configuration
@EnableWebSecurity
public class SpringSecurityConfig {

    public final CustomUserDetailsService customUserDetailsService;

    private final JwtRequestFilter jwtRequestFilter;

    public SpringSecurityConfig(CustomUserDetailsService customUserDetailsService, JwtRequestFilter jwtRequestFilter) {
        this.customUserDetailsService = customUserDetailsService;
        this.jwtRequestFilter = jwtRequestFilter;
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public AuthenticationManager authenticationManager(HttpSecurity http) throws Exception {
        return http.getSharedObject(AuthenticationManagerBuilder.class)
                .userDetailsService(customUserDetailsService)
                .passwordEncoder(passwordEncoder())
                .and()
                .build();
    }


    @Bean
    protected SecurityFilterChain filter (HttpSecurity http) throws Exception {

        http
                .csrf().disable()
                .httpBasic().disable()
                .cors().and()
                .authorizeHttpRequests()
                .requestMatchers("/**").permitAll()
                .requestMatchers(HttpMethod.POST, "/users").permitAll()

                .anyRequest().denyAll()
                .and()
                .logout()
                .logoutSuccessUrl("/") // Redirect after successful logout
                .permitAll() // Allow access to the logout URL
                .and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
        return http.build();
    }

}

Before i realised Spring Security had its own default '/logout' path and functionality, i have tried creating my own logout functionality inside my Authentication controller. But when i tested that trough Postman, doing a POST request to /logout: It returned a 400 error and as a path it showed '/login' even though i was sending the post to '/logout'.

Also i tried to manually visit localhost:8080/logout and it would redirect me to localhost:8080/login?logout

After that i realised Spring Security has its own default '/logout' like i already said so i deleted the manual logout functionality inside the AuthenticateController

  • You can not logout a JWT, there is no way around it. And storing JWTs in local storage is a huge security risk and bad practice, infact using JWTs as a session baerer is a huge security risk. Session information should be stored in cookies with the httponly flag set. – Toerktumlare Aug 15 '23 at 16:07
  • Spring security does not use jwts as they know its insecure to use them as sessions, but instead of reading the actual docs you have followed som poor blog/tutorial and built something insecure from someone that does not know anything about security. I suggest you read the docs and implement FormLogin using cookies as it is way more secure and correct. – Toerktumlare Aug 15 '23 at 16:09
  • Okay, thank you I'll reconstruct the Login – Developsom Aug 15 '23 at 16:34
  • i should mention tho, in this application there is no transactions or financial information available does that make a difference? – Developsom Aug 15 '23 at 16:48
  • Why would that effect the security? – Toerktumlare Aug 15 '23 at 21:37
  • I actually managed to 'log out' a jwt token? @Toerktumlare ? Simply by clearing the jwt token from the cache – Developsom Aug 21 '23 at 10:59
  • clearing a jwt from the cache does not logout anything, if i get a hold of your jwt, and you clear your cache i can still send the JWT to your server and the server will verify it as valid and it can still be used. So once again, you can not logout a JWT – Toerktumlare Aug 21 '23 at 13:56
  • Aha, alright thank you for further clarification @Toerktumlare – Developsom Sep 01 '23 at 09:20
  • Does this answer your question? [How to destroy JWT Tokens on logout?](https://stackoverflow.com/questions/37959945/how-to-destroy-jwt-tokens-on-logout) – Toerktumlare Sep 01 '23 at 10:04

1 Answers1

-2
function logout() {
    localStorage.clear();
    toggleIsAuth( {
        isAuth: false,
        user: null,
        status: 'done',
    } );

    console.log( 'Gebruiker is uitgelogd!' );
    navigate( '/' );
}
  • Avoid code only answer and provide an explanation. – Itération 122442 Aug 22 '23 at 11:51
  • how does the above in react tell the spring to process the logout procedure? – Man Man Yu Aug 30 '23 at 06:26
  • Tho code provided does only remove the JWT from the browser. The JWT is still valid and can still be used to perform requests against the backend server. If the token is stolen through an XSS bu running malicious javascript on the webpage, the evil javascript can without any problems read the token from local storage and steal the token, and the user cant do anything about it. ALl the user can do is to remove the token from the browser, but the token stealer can use the token still – Toerktumlare Sep 01 '23 at 23:17