HM-85. Внедрена авторизация на сайт (#44)
This commit is contained in:
@ -33,11 +33,19 @@ class AuthServiceApi {
|
||||
*/
|
||||
refresh = () => {
|
||||
const refresh_token = tokenApi.getRefreshToken();
|
||||
if (refresh_token) {
|
||||
return axios.post(`${this.URL}${AUTH_ENDPOINTS.REFRESH}`, {refresh_token})
|
||||
.then(({data: tokens}) => {
|
||||
tokenApi.saveTokenPair(tokens);
|
||||
})
|
||||
.catch((e) => {
|
||||
tokenApi.clearTokents();
|
||||
throw e;
|
||||
});
|
||||
}
|
||||
|
||||
return Promise.reject(new Error('Не авторизован'));
|
||||
}
|
||||
}
|
||||
|
||||
const authServiceApi = new AuthServiceApi();
|
||||
|
||||
@ -26,64 +26,64 @@ class HttpApi {
|
||||
* @param {string} url - адрес запроса
|
||||
* @param {Object} body - тело запроса
|
||||
*/
|
||||
request = (method, url, body) => {
|
||||
return httpAuthApi.request({method, url, body});
|
||||
request = (method, url, body, config) => {
|
||||
return httpAuthApi.request({...config, method, url, body});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} url - адрес запроса
|
||||
* @param {Object<string, string>} query - параметры для передачи через query
|
||||
*/
|
||||
get = (url, query) => {
|
||||
return this.request(GET, makeUrlWithQuery(url, query));
|
||||
get = (url, query, config) => {
|
||||
return this.request(GET, makeUrlWithQuery(url, query), null, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} url - адрес запроса
|
||||
* @param {Object} body - тело запроса
|
||||
*/
|
||||
post = (url, body) => {
|
||||
return this.request(POST, url, body);
|
||||
post = (url, body, config) => {
|
||||
return this.request(POST, url, body, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} url - адрес запроса
|
||||
* @param {Object} body - тело запроса
|
||||
*/
|
||||
put = (url, body) => {
|
||||
return this.request(PUT, url, body);
|
||||
put = (url, body, config) => {
|
||||
return this.request(PUT, url, body, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} url - адрес запроса
|
||||
* @param {Object<string, string>} query - параметры для передачи через query
|
||||
*/
|
||||
delete = (url, query) => {
|
||||
return this.request(DELETE, makeUrlWithQuery(url, query));
|
||||
delete = (url, query, config) => {
|
||||
return this.request(DELETE, makeUrlWithQuery(url, query), null, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} url - адрес запроса
|
||||
* @param {Object<string, string>} query - параметры для передачи через query
|
||||
*/
|
||||
head = (url, query) => {
|
||||
return this.request(HEAD, makeUrlWithQuery(url, query));
|
||||
head = (url, query, config) => {
|
||||
return this.request(HEAD, makeUrlWithQuery(url, query), null, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} url - адрес запроса
|
||||
* @param {Object<string, string>} query - параметры для передачи через query
|
||||
*/
|
||||
options = (url, query) => {
|
||||
return this.request(OPTIONS, makeUrlWithQuery(url, query));
|
||||
options = (url, query, config) => {
|
||||
return this.request(OPTIONS, makeUrlWithQuery(url, query), null, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} url - адрес запроса
|
||||
* @param {Object} body - тело запроса
|
||||
*/
|
||||
path = (url, body) => {
|
||||
return this.request(PATH, url, body);
|
||||
path = (url, body, config) => {
|
||||
return this.request(PATH, url, body, config);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -90,6 +90,7 @@ class HttpAuthApi {
|
||||
addTokenToRequest = (requestConfig) => ({
|
||||
...requestConfig,
|
||||
headers: {
|
||||
...(requestConfig.headers ?? {}),
|
||||
'Authorization': tokenApi.getAccessToken(),
|
||||
},
|
||||
})
|
||||
|
||||
@ -16,7 +16,7 @@ class LocalStorageAPI {
|
||||
* Возвращает распарсенный объект из Local Storage по ключу из конструктора
|
||||
*/
|
||||
request () {
|
||||
const value = this.api.getItem(this.key) || '{}';
|
||||
const value = this.api.getItem(this.key) || 'null';
|
||||
return JSON.parse(value);
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import axios from 'axios';
|
||||
import {ENDPOINTS} from './consts';
|
||||
import adminConfigsService from '../services/AdminConfigsService';
|
||||
import http from './HttpAPI';
|
||||
|
||||
class StorageLogsApi {
|
||||
constructor () {
|
||||
@ -9,22 +9,22 @@ class StorageLogsApi {
|
||||
}
|
||||
|
||||
requestServerLogs = async () => {
|
||||
const {data} = await axios.get(`${this.URL}${ENDPOINTS.SERVER_LOGS}`);
|
||||
const {data} = await http.get(`${this.URL}${ENDPOINTS.SERVER_LOGS}`);
|
||||
return data;
|
||||
}
|
||||
|
||||
requestClientLogs = async () => {
|
||||
const {data} = await axios.get(`${this.URL}${ENDPOINTS.CLIENT_LOGS}`);
|
||||
const {data} = await http.get(`${this.URL}${ENDPOINTS.CLIENT_LOGS}`);
|
||||
return data;
|
||||
}
|
||||
|
||||
deleteAllServerLogs = async () => {
|
||||
const {data} = await axios.delete(`${this.URL}${ENDPOINTS.SERVER_LOGS}`);
|
||||
const {data} = await http.delete(`${this.URL}${ENDPOINTS.SERVER_LOGS}`);
|
||||
return data;
|
||||
}
|
||||
|
||||
deleteAllClientLogs = async () => {
|
||||
const {data} = await axios.delete(`${this.URL}${ENDPOINTS.CLIENT_LOGS}`);
|
||||
const {data} = await http.delete(`${this.URL}${ENDPOINTS.CLIENT_LOGS}`);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import axios from 'axios';
|
||||
|
||||
import {ENDPOINTS} from './consts';
|
||||
import adminConfigsService from '../services/AdminConfigsService';
|
||||
import http from './HttpAPI';
|
||||
|
||||
/**
|
||||
* @interface Store
|
||||
@ -29,7 +28,7 @@ class StorageServiceApi {
|
||||
* @returns {Promise<Store[]>} - Возвращает список всех api
|
||||
*/
|
||||
request = async () => {
|
||||
const {data} = await axios.get(this.URL, this.OPTIONS);
|
||||
const {data} = await http.get(this.URL, null, this.OPTIONS);
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -39,7 +38,7 @@ class StorageServiceApi {
|
||||
* @returns {Promise<Store>} - Возвращает api по указанному ключу
|
||||
*/
|
||||
find = async (key) => {
|
||||
const {data} = await axios.get(`${this.URL}/${key}`, this.OPTIONS);
|
||||
const {data} = await http.get(`${this.URL}/${key}`, null, this.OPTIONS);
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -49,7 +48,7 @@ class StorageServiceApi {
|
||||
* @returns {Promise<Store>} - Возвращает вновь созданный элемент
|
||||
*/
|
||||
create = async (createData) => {
|
||||
const {data} = await axios.post(this.URL, createData, this.OPTIONS);
|
||||
const {data} = await http.post(this.URL, createData, this.OPTIONS);
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -59,7 +58,7 @@ class StorageServiceApi {
|
||||
* @returns {Promise<Store>} - Возвращает обновленный элемент
|
||||
*/
|
||||
update = async (updateData) => {
|
||||
const {data} = await axios.put(this.URL, updateData, this.OPTIONS);
|
||||
const {data} = await http.put(this.URL, updateData, this.OPTIONS);
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -69,7 +68,7 @@ class StorageServiceApi {
|
||||
* @returns {Promise<Store>} - Возвращает удаленный элемент
|
||||
*/
|
||||
remove = async (key) => {
|
||||
const {data} = await axios.delete(`${this.URL}/${key}`, this.OPTIONS);
|
||||
const {data} = await http.delete(`${this.URL}/${key}`, null, this.OPTIONS);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,14 +33,14 @@ class TokenApi {
|
||||
* Возвращает токен авторизации
|
||||
*/
|
||||
getAccessToken = () => {
|
||||
return this.localApi.request();
|
||||
return this.sessionApi.request();
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает токен ревреша авторизации
|
||||
*/
|
||||
getRefreshToken = () => {
|
||||
return this.sessionApi.request();
|
||||
return this.localApi.request();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -39,7 +39,7 @@ export const AUTH_SERVICE = 'http://api.auth.vigdorov.ru';
|
||||
|
||||
export const AUTH_ENDPOINTS = {
|
||||
AUTH: '/auth',
|
||||
REFRESH: '/refresh',
|
||||
REFRESH: '/auth/refresh',
|
||||
};
|
||||
|
||||
export const LOCAL_STORAGE_TYPE = {
|
||||
|
||||
33
src/app.js
33
src/app.js
@ -5,17 +5,20 @@ import 'bootstrap';
|
||||
import './services/AdminConfigsService';
|
||||
import ApiPage from './components/api-page';
|
||||
import MainPage from './components/main-page';
|
||||
import mainMenu from './components/main-menu/MainMenu';
|
||||
import MainMenu from './components/main-menu/MainMenu';
|
||||
import routeService from './services/RouteService';
|
||||
import RouterPagesContainer from './components/router-pages-container/index';
|
||||
import LogsPage from './components/logs-page/index';
|
||||
import LoginPage from './components/login-page';
|
||||
import authServiceApi from './api/AuthServiceAPI';
|
||||
|
||||
mainMenu.render();
|
||||
const initAppComponents = () => {
|
||||
const mainMenu = new MainMenu();
|
||||
mainMenu.render();
|
||||
|
||||
const routerPagesContainer = new RouterPagesContainer(mainMenu);
|
||||
const routerPagesContainer = new RouterPagesContainer(mainMenu);
|
||||
|
||||
/**
|
||||
/**
|
||||
* Добавление страниц в Роутинг выполняется на странице app.js
|
||||
* @example
|
||||
* routerPagesContainer.addRoutes([
|
||||
@ -23,18 +26,32 @@ const routerPagesContainer = new RouterPagesContainer(mainMenu);
|
||||
* {url: '/api', pageComponent: ApiPage},
|
||||
* ]);
|
||||
*/
|
||||
routerPagesContainer.addRoutes([
|
||||
routerPagesContainer.addRoutes([
|
||||
{url: '/', pageComponent: MainPage},
|
||||
{url: '/api', pageComponent: ApiPage},
|
||||
{url: '/logs', pageComponent: LogsPage},
|
||||
{url: '/login', pageComponent: LoginPage},
|
||||
]);
|
||||
]);
|
||||
|
||||
/**
|
||||
/**
|
||||
* Этот метод генерит событие Route, чтобы все компоненты получили его после инициализации.
|
||||
* Поэтому вызывать его надо в самом конце, когда уже созданы все компоненты приложения.
|
||||
* @example
|
||||
* // Вызывать его можно только один раз в программе
|
||||
* routeService.init();
|
||||
*/
|
||||
routeService.init();
|
||||
routeService.init();
|
||||
};
|
||||
|
||||
const initApp = () => {
|
||||
authServiceApi.refresh()
|
||||
.then(() => {
|
||||
initAppComponents();
|
||||
})
|
||||
.catch(() => {
|
||||
history.pushState({}, '', '/login');
|
||||
initAppComponents();
|
||||
});
|
||||
};
|
||||
|
||||
initApp();
|
||||
|
||||
@ -3,6 +3,7 @@ import './LoginPage.css';
|
||||
import LoginForm from '../login-form';
|
||||
import authServiceApi from '../../api/AuthServiceAPI';
|
||||
import routeService from '../../services/RouteService';
|
||||
import notify from '../../services/NotifyService';
|
||||
|
||||
class LoginPage extends Component {
|
||||
constructor (mainNodeSelector, parentNode) {
|
||||
@ -15,12 +16,12 @@ class LoginPage extends Component {
|
||||
authServiceApi.auth(login, password)
|
||||
.then(() => {
|
||||
this.form.disabled(false);
|
||||
notify.success('Вы авторизованы');
|
||||
routeService.goTo('/');
|
||||
})
|
||||
.catch((e) => {
|
||||
// TODO: Времено используется alert, потом прикрутим систему нотификаций
|
||||
// eslint-disable-next-line no-alert
|
||||
alert(e?.response?.data?.message || 'Неизвестная ошибка');
|
||||
const message = e?.response?.data?.message || 'Неизвестная ошибка';
|
||||
notify.warn(message);
|
||||
this.form.disabled(false);
|
||||
});
|
||||
});
|
||||
|
||||
@ -82,6 +82,4 @@ class MainMenu extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
const navMenuButtons = new MainMenu();
|
||||
|
||||
export default navMenuButtons;
|
||||
export default MainMenu;
|
||||
|
||||
@ -36,7 +36,7 @@ class AdminConfigsService {
|
||||
* @param {'api-p' | 'api-t' | 'api-l'} apiName - api с которым хотим работать
|
||||
* @example
|
||||
* // Переключаем api на localhost, пишем в консоли браузера
|
||||
* __adminConfigs.setApi('api-l')
|
||||
* __adminConfig.setApi('api-l')
|
||||
*/
|
||||
setApi (apiName) {
|
||||
const options = this.getOptions();
|
||||
@ -53,7 +53,7 @@ class AdminConfigsService {
|
||||
const adminConfigsService = new AdminConfigsService();
|
||||
|
||||
if (location.hostname === LOCALHOST) {
|
||||
window.__adminConfigs = adminConfigsService;
|
||||
window.__adminConfig = adminConfigsService;
|
||||
}
|
||||
|
||||
export default adminConfigsService;
|
||||
|
||||
Reference in New Issue
Block a user