我想创建一个包含登录信息的反应式网络应用。我的后端是通过JAX-RS和BASIC身份验证实现的。以下是web.xml
和Resource
的摘要。
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
<security-constraint>
<web-resource-collection>
<web-resource-name>api</web-resource-name>
<url-pattern>/api/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>ROLE</role-name>
</auth-constraint>
</security-constraint>
<security-role>
<role-name>ROLE</role-name>
</security-role>
资源:
@GET
@PermitAll
@Produces(MediaType.APPLICATION_JSON)
public List<OnlineStackDto> getData() {
return dataService.getData();
}
来自react的所有请求都捆绑在一个文件request.js
中。以下是get函数的示例。
const user = 'username';
const pass = 'password';
export function get(url) {
return fetch(url,
{
method: 'GET',
headers: {
Authorization: "Basic " + btoa(user + ":" + pass)
}
}
);
}
当然,硬编码用户名和密码并不是以后应用程序的部署方式。该函数调用如下:
import {get} from "./request";
import React from "react";
export default class DataComponent extends React.Component {
componentDidMount() {
get('onlinestacks').then(data => this.setState({myData: data}));
}
}
使用react-router
和React 16.3 Context-API实现登录逻辑。因此,我可以使用Consumer
访问每个组件中的用户名/密码。以下是如何设置和使用数据的示例。有关更完整的示例,请参阅this question。
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
user: {
username: '',
password: ''
}
};
this.login = this.login.bind(this);
}
login(username, password) {
this.setState({
user: {
username: username,
password: password
}
});
}
render() {
return (
<UserContext.Provider value={this.state.user}>
<Header/>
/*Other Components*/
</UserContext.Provider>
);
}
}
export default class Header extends React.Component {
render() {
return (<header>
<UserContext.Consumer>{value =>
<div className="username">{value.username}</div>
}
</UserContext.Consumer>
</header>);
}
}
我的问题是:
如何在我的请求中使用Context中的用户名和密码,而每次我想要发送请求时都必须传递它们?
答案 0 :(得分:1)
有很多可能的解决方案。您可以使用bind
方法并传递绑定的get
方法,并设置用户名和密码。因此,您获得的功能将接受username
和password
作为参数
export function get(username, password, url)
而Context.Provider将传递绑定函数
<UserContext.Provider value={get.bind(null,this.state.user,this.state.password)}>
要不触发回流,您可以解除绑定
login(username, password){
this.setState({
authenticatedGet: get.bind(null,username,password)
});
}
//....
<UserContext.Provider value={this.state.authenticatedGet}>
我真的不认为你应该使用Context来做这种事情。事情是上下文对于UI逻辑是好的,这更多地是关于服务层。还有许多其他解决方案,包括在适当情况下将get
作为道具传递,或者如果您将redux
与redux-thunk
一起使用,则将其作为thunk.withExtraArgument
传递,但这实际上超出了您的问题的范围