首页 > 解决方案 > 反应商店会话

问题描述

我通过以下代码做出反应登录到我的后端:

export function PostData(type, userData) {

let BaseUrl = 'http://localhost:8080/';

return new Promise((resolve, reject) => {
let formData = new FormData();
formData.append('username', userData.username);
formData.append('password', userData.password);

fetch(BaseUrl + type, {
  method: 'POST',
  body: formData,
})
.then((responseJson) => {
  console.log(responseJson);
  resolve(responseJson);
})
.catch((error) => {
  reject(error);
});

}); }

接下来我想通过这个从其他网址获取数据:

import React, { Component } from 'react';

class Datas extends Component {
  constructor(props) {
    super(props);
    this.state = {
      items: [],
      isLoaded: false
    }
  }
  componentDidMount() {

      fetch('http://localhost:8080/api/tasks/', {
        headers : {
          'Content-Type': 'application/json',
          'Accept': 'application/json'
        }
      })
      .then(response => { return response.json() })
      .then(results => this.setState({
        tasks: results,
        isLoading: false
      }));

  }
  render() {
    var { isLoaded, items } = this.state;
    if (!isLoaded) {
      return <div>Loading...</div>;
    }
    return (
        <div classname="App">

          <ul>
            {items.map(item => (
                <li key="{item.id}">
                  Name: {item.name} | Email: {item.description}
                </li>
            ))}
          </ul>
        </div>
    );
  }
}
export default Datas;

但我收到错误 401:未经授权,所以我的问题是如何获取数据,我应该以某种方式存储会话吗?我想如果我登录到我的后端应用程序并收到状态为 200 的消息,默认我可以做我想要的请求。请关于帮助/提示

弹簧安全配置:

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

  @Autowired
  private MyUserDetailsService userDetailsService;

  @Autowired
  private UserRepository userRepository;

  @Autowired
  private RestAuthenticationEntryPoint restAuthenticationEntryPoint;

  @Autowired
  private MySavedRequestAwareAuthenticationSuccessHandler mySuccessHandler;

  private SimpleUrlAuthenticationFailureHandler myFailureHandler = new SimpleUrlAuthenticationFailureHandler();

  @Override
  protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
    auth.authenticationProvider(authenticationProvider());
  }

  @Bean
  public DaoAuthenticationProvider authenticationProvider() {
    DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
    authProvider.setUserDetailsService(userDetailsService);
    authProvider.setPasswordEncoder(encoder());
    return authProvider;
  }

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

  @Override
  protected MyUserDetailsService userDetailsService() {
    return userDetailsService;
  }

  @Bean
  public SimpleSocialUserDetailsService simpleSocialUserDetailsService() {
    return new SimpleSocialUserDetailsService(userRepository);
  }

  @Override
  protected void configure(final HttpSecurity http) throws Exception {
    http
          .cors()
        .and()
          .csrf().disable()
          .exceptionHandling().authenticationEntryPoint(restAuthenticationEntryPoint)
        .and()
          .authorizeRequests()
          .antMatchers("/login*", "/success*").anonymous()
          .antMatchers("/auth/**", "/signup/**", "/css/*", "/webjars/**","/js/*","/image/*").permitAll()
          .anyRequest().authenticated()
        .and()
          .formLogin()
          .successHandler(mySuccessHandler)
          .failureHandler(myFailureHandler)
          .loginProcessingUrl("perform_login")
//          .successForwardUrl("/tasks")
        .and()
          .logout()
          .logoutUrl("/logout")
          .logoutSuccessUrl("/logout-success").permitAll()
        .and()
          .apply(new SpringSocialConfigurer());
  }

  @Bean
  CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedMethods(Arrays.asList("HEAD",
        "GET", "POST", "PUT", "DELETE", "PATCH"));
    configuration.setAllowCredentials(true);
    configuration.setAllowedHeaders(Arrays.asList("Authorization", "Cache-Control", "Content-Type"));
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
  }

}

标签: reactjssessionlogin

解决方案


您的/login端点是匿名的,这意味着它在尝试访问它之前不需要任何身份验证,它只需要一些数据(凭据)并返回一些东西(可能是身份验证令牌)。然后,您可以存储该令牌 ( localStorage ) 并将其作为'Authorization: '(Bearer/Basic) _YOUR_TOKEN_'与您的 API 调用一起传递到标头中。

编辑:

如果您在登录后获得令牌,您可以执行以下操作:

localStorage.setItem('__MY_TOKEN__', response.data.access_token)

然后创建一个辅助函数来获取并自动为您注入标头:

 function apiCall(url, method = 'GET', body) {
    return fetch(url, {
       method,
       body,
       headers: {
         'Accept': 'application/json',
         'Content-Type': 'application/json',
         'Authorization': 'Bearer ' + localStorage.getItem('__MY_TOKEN__')
      }
    })
 }

然后代替fetch(...).then(...)你可以使用apiCall(' http://localhost:8080/api/tasks ').then(...)

授权类型和内容取决于您的后端。我的解决方案基于您收到访问令牌的假设。


推荐阅读