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