reactjs - 反应商店会话
问题描述
我通过以下代码做出反应登录到我的后端:
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;
}
}
解决方案
您的/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(...)
授权类型和内容取决于您的后端。我的解决方案基于您收到访问令牌的假设。
推荐阅读
- python-3.x - SMTPAuthenticationError 在 /
- python - 如何在 Django Rest Framework 中显示 ManyToMany 字段的值而不是它们的 Id?
- node.js - UUID 依赖项中的 googleapis-common 抛出错误
- kubernetes - 具有一个 Job manager 的单个 Flink Cluster 中的理想任务管理器数量
- python - 当我更改 python pandas 数据框中的索引时,matplotlib 图表发生了变化
- php - Symfony 表单提交后提交填充实体类型
- string - 如何将制表符分隔的数据(始终以字母开头)合并为一个字符串?
- javascript - 为什么 react render 接受一个块而 return 不接受?
- sparql - 如何列出自定义 Wikibase 实例上的所有属性
- moodle - 根据用户角色创建 CSS 类