Search code examples
reactjsspring-bootspring-mvcspring-securityreact-router

(SpringBoot + React.js) Whitelabel error page - Resource not found


I ran into a problem, I wrote a page on the React to reset the password, when I run only the React application and click on the link 127.0.0.1:8080/user/resetPassword/53442 everything is displayed well. As soon as I run in bundle with Spring Boot, whitelabel error page type = 404 appears. And in the Spring log I get this:

GET "/ user / resetPassword / afsa11", parameters = {}

Mapped to `ResourceHttpRequestHandler [URL [file: C: / Users / Jake Morgan / IdeaProjects / react-invasion / build / index.html]]

Resource not found

I did not write any controller for this patch and do not use model view, because I don’t need it there, I make a request to another point after entering the form through Axios.

Most likely I missed something and forgot some setting.

Maybe doFilter?

My App.js - React:

import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css'
import Header from './Components/Header';
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import Home from './Pages/Home';
import PasswordResetPage from './Pages/PasswordResetPage';
import Test from './Components/Test';

function App() {
 return (
<>
  <div className="App">
    <Router>
      <Switch>
        <Route path="/vasua/" component={Test}/>
        <Route path="/user/resetPassword/:id" component={PasswordResetPage} />
        <Route exact path="/" component={Home} />
      </Switch>
    </Router>
  </div>
  <Header />
</>
);
}

export default App;

My MvcSecurityConfig:

@Value("${path.frontend}")
private String frontendPath;
@Value("${frontendStaticResourcesPathPatterns}")
private String[] frontendStaticResourcesPathPatterns;
private static final String BASE_API_PATH = "/";

public void addResourceHandlers(ResourceHandlerRegistry registry){
    String pathToFrontend = "file:" + this.frontendPath;
    String pathToIndexHTML = pathToFrontend + "index.html";

    registry
            .addResourceHandler(frontendStaticResourcesPathPatterns)
            .setCachePeriod(0)
            .addResourceLocations(pathToFrontend);

    registry.addResourceHandler("/", "/**")
            .setCachePeriod(0)
            .addResourceLocations(pathToIndexHTML)
            .resourceChain(true)
            .addResolver(new PathResourceResolver() {
                @Override
                protected Resource getResource(String resourcePath, Resource location) throws IOException {
                    if (resourcePath.startsWith(BASE_API_PATH) || resourcePath.startsWith(BASE_API_PATH.substring(1))) {
                        return null;
                    }
                    return location.exists() && location.isReadable() ? location : null;
                }
            });

}

My web security config:

@EnableWebSecurity
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    UserDetailsServiceImpl userDetailsService;

    @Autowired
    private AuthEntryPointJwt unauthorizedHandler;

    @Bean
    public AuthTokenFilter authenticationJwtTokenFilter() {
        return new AuthTokenFilter();
    }

    @Override
    public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
        authenticationManagerBuilder
            .userDetailsService(userDetailsService)
            .passwordEncoder(passwordEncoder());
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

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

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .cors()
                .and()
            .csrf().disable()
            .exceptionHandling()
                .authenticationEntryPoint(unauthorizedHandler)
                .and()
            .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
            .authorizeRequests()
                .antMatchers(
                    "/user/forgotPassword",
                    "/user/resetPassword",
                    "/user/resetPassword/*",
                    "/user/resetPassword/**/",
                    "/api/auth/*",
                    "/api/auth/**").permitAll()
                .antMatchers(
                    "/",
                    "/favicon.ico",
                    "/static/**",
                    "/manifest.json",
                    "/logo192.png",
                    "/index.html").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin().disable();

        http
            .addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
    }
}

Folder:

    C:/Users/Jake Morgan/IdeaProjects/react-invasion/build/
|   asset-manifest.json
|   favicon.ico
|   index.html
|   logo192.png
|   logo512.png
|   manifest.json
|   robots.txt
|   tree.txt
|   
\---static
    +---css
    |       2.818011ed.chunk.css
    |       2.818011ed.chunk.css.map
    |       main.6745c9b9.chunk.css
    |       main.6745c9b9.chunk.css.map
    |       
    +---js
    |       2.d6a0ce6c.chunk.js
    |       2.d6a0ce6c.chunk.js.LICENSE.txt
    |       2.d6a0ce6c.chunk.js.map
    |       3.c6fb18dc.chunk.js
    |       3.c6fb18dc.chunk.js.map
    |       main.a7a27014.chunk.js
    |       main.a7a27014.chunk.js.map
    |       runtime-main.197b0595.js
    |       runtime-main.197b0595.js.map
    |       
    \---media
            Invasion-Project.0dba6a23.exe
            mov.41f2b828.mp4
            start.e3a0d02b.png
            x.85f9f2a1.svg

Application.properties

#Frontend
path.frontend = C:/Users/Jake Morgan/IdeaProjects/react-invasion/build/
frontendStaticResourcesPathPatterns=/**/*.css,/**/*.html,/**/*.js,/**/*.jsx,/**/*.png,/**/*.ttf,/**/*.woff,/**/*.woff2,/**/*.ico,/**/*.jpg,/**/*.mp4,/**/*.svg,manifest.json
spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,file:${path.frontend}

UPDATE

I added HashRouter to my React.js instead of BrowserRouter and now the page opens, but at this address:

import { HashRouter as Router, Switch, Route } from "react-router-dom";

127.0.0.1:8080/#/user/resetPassword/412 What is this # sign and can it be removed?


Solution

  • Found a problem

    private static final String BASE_API_PATH = "/";
    

    Correct:

    private static final String BASE_API_PATH = "/api";