Я хочу создать реагирующее веб-приложение, содержащее логин. Мой бэкэнд реализован с аутентификацией 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();
}
Все запросы от реакции объединены в один файл 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
. Вот пример того, как данные устанавливаются и используются. Более полный пример см. в этом вопросе.
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 в своих запросах, без передачи их каждый раз, когда я хочу сделать запрос?
UserContext
. Я могу получить к нему доступ, как показано в компонентеHeader
. Я не знаю, как использовать эти данные в файлеrequest.js
. Просто установить его как глобальную переменную кажется неправильным, и единственный другой способ, который я мог придумать, - это передать пользователя в качестве параметра запроса, напримерfunction get(url, user)
. Но это потребовало бы реализацииUserContext.Consumer
в каждом компоненте, который должен получать данные. Это кажется излишне сложным. - person SilverNak   schedule 15.04.2018request
? Предлагаемое решение будет зависеть от этого. Есть много способов сделать это, и у каждого есть свои недостатки. - person Moti Korets   schedule 15.04.2018DataComponent
, дающий пример запросаget
- person SilverNak   schedule 16.04.2018