我想创建一个包含登录名的 React 网络应用程序。我的后端是使用 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>);
}
}
我的问题是:
如何在我的请求中使用上下文中的用户名和密码, 每次我想发出请求时都必须传递它们?
最佳答案
对此有许多可能的解决方案。您可以使用 bind
方法并传递绑定(bind)的 get
方法,并设置用户名和密码。所以你得到的函数将接受 username
和 password
作为参数
export function get(username, password, url)
你的 Context.Provider 将传递绑定(bind)函数
<UserContext.Provider value={get.bind(null,this.state.user,this.state.password)}>
要不触发回流,您可以解除绑定(bind)
login(username, password){
this.setState({
authenticatedGet: get.bind(null,username,password)
});
}
//....
<UserContext.Provider value={this.state.authenticatedGet}>
不过,我真的不认为您应该将 Context 用于此类内容。问题是 Context 对 UI 逻辑有好处,这更多是关于服务层。还有许多其他解决方案,包括在适当的地方将 get
作为 prop 传递,或者如果您将 redux
与 redux-thunk
一起使用,将其作为 thunk 传递.withExtraArgument
但这确实超出了您的问题范围。
关于javascript - react : Implement Login with BASIC Authentication,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49831775/