Free React For Beginners
3.46K subscribers
231 photos
5 videos
1 file
385 links
💻 Про #React та #frontend та #веб розробку
🧑‍🎓 Для початківців і не тільки

👉 https://www.youtube.com/@reactdev
Download Telegram
SOLID, прямий ефір в понеділок 03.04.22, 19:00


🎙А давайте таки зробимо прямий ефір, щось я за ними вже скучив. Поговоримо про SOLID, про інші принципи, та й загалом поспілкуємося. Я ще й якихось подарунків зараз вам нашукаю, розіграємо щось маленьке, але приємне.

👉 Так що резервуйте собі вечір наступного понеділка і приходьте, буду всіх радий бачити!

👩‍🏫 А поки що буду вас знайомити з веб вразливостями - XSS, XSRF, Prototype Pollution.

Бережіть себе, і пам'ятайте - "всеодно добро, "закохає" зло" (С) ТНМК
❤‍🔥21👍10🤝3🔥21
Web Vulnerabilities #1 - XSS

💡Сама ідея вразливості дуже проста: це всього-навсього виконання чужого JavaScript коду на веб сторінці.

🪲 Оскільки в JS немає жодних рівнів привілегій, то, фактично, код виконується від імені сторінки з усіма її можливостями і зловмисник може творити що завгодно, від логування всіх дій користувача до передачі відео з камери куди треба. Як ви розумієте, сценаріїв експлуатації безліч тому XSS вважається досить небезпечною вразливістю.

❗️Виникає XSS тоді, коли ви виводити на сторінку дані від користувача або з інших систем як є, без їх "знешкодження", або з не повним знешкодженням.

До прикладу уявіть собі форум пасічників на якому ви пишете наступний пост:

Бджоли рулять!!!
<script>alert('ТАК!');</script>

✍️ Якщо виводити цей контент як є (доприкладу через .innerHTML=), станеться наступне: текст з'явиться як текст, а от script секція буде додана саме як script. Браузер цей скрипт виконає і користувач побачить вікошко з текстом десь з 2004 року.

Звичайно всі адекватні фреймоврки про цю проблему знають і біль-менш успішно її успішно її вирішують. Але є три моменти

1️⃣ По-перше, не завжди ми використовуємо фреймворки взагалі, іноді в проді лежать самописки або якісь екзоти. Та й element.innerHTML = USER_INPUT_PLEASE_NO ніхто не відміняв, навіть в тому ж React. (не робіть так)

2️⃣ По-друге, фреймворки не святі. В React-і була проблема з серіалізованим стейтом сторінки під час server-side-rendering. Особливо не пояснюю, бо проблема давно вирішена, але це чудова ілюстрація того, що навіть стабільні фреймворки бувають вразливі.

3️⃣ По-третє, всі фреймворки мають спосіб як обійти санітанізацію (тобто знешкодження) контенту, тому що це буває потрібно. Уявіть собі що вам потрібно рендерити якийсь HTML з бази даних або з іншого сервісу. Ось тут без обходу знешкодження ніяк. І якщо ви зробите її некоректно, або хтось отримає доступ до джерела цієї розмітки - ви в повній дупі і цей вираз навіть на половину не передає рівень ваших проблем.

А от як з цим боротися - наступному пості.
@reactbeginners
👍164
Можливо всі вже бачили, але хочу вам показати відео від Майкла Щура про одного не дуже добросовісного інструктора.

Це відео піднімає дві важливі проблеми:

1️⃣ Інфоциганщина як така, тобто неякісне навчання просто за гроші. Нажаль таке буває і з IT курсами.

2️⃣ Безвідповідальність в такій особливо небезпечній сфері як збройова. З врахуванням того, що декому ці навички потрібні для банального виживання на полі бою, цензурних слів у мене мало.

Відео до перегляду
👍25🔥3
Web Vulnerabilities #2 - XSS - як боротися.

З тим що таке XSS ми наче трохи розібралися. Щоб закріпити матеріал, раджу спробувати самому таку просту вправу:

Cтворіть форму з textArea та реалізуйте логіку додавання повідомлень під форму за допомогою innerHTML або аналогів. Потім спробуйте підпихнути туди код який ввімкне камеру, або зробить запит на будь-яку API на фоні. Можна взяти React та dangerouslySetInnerHTML

Тепер давайте перейдемо до засобів боротьби з XSS.

1️⃣ Використовуйте перевірені фреймоврки або бібліотеки, які вміють знешкоджувати XSS з коробки - наприклад ті самі Angular, React або Vue.

2️⃣ Якщо ви не можете в п.1 (буває таке 😢 в самописних фреймворках або зарегульованих компаніях) - використовуйте спеціальні бібліотеки для знешкодження контенту. Не робіть власні "велосипеди", якщо ви тому спеціально не навчалися. Тема XSS дуже складна і помилитися дуже і дуже просто.

3️⃣ Налаштуйте npm audit (бажано на рівні CI) щоб бачити знайдені вразливості у ваших залежностях. А npm audit fix допоможе виправити частину з них.

4️⃣ Не обходьте захист бібліотек від XSS аж допоки це не стане абсолютно необхідно. І навіть в цьому випадку, шукайте можливість дозволити не весь HTML, а лише мінімальний набір тегів та атрибутів, який вам потрібен.

5️⃣ Використовуйте додаткові способи захисту: Content-Security-Policy Header, Permission-Policy Header (буде окремий пост). Це зменшить вектори атак та зменшить шкоду, яку зловмисник зможе завдати.

6️⃣ Завжди ставтеся до будь-яких чужих даних як до шкідливих. Не важливо чи це - користувацький ввід або 3rd party система. Зламають її, зламають і вас. До-речі, ви ж в курсі, що window.location.href містить саме користувацькі дані, правда ж?

Тепер щодо React. Якщо вам потрібно вивести HTML, для цього є метод dangerouslySetInnerHTML, який є просто обгорткою над .innerHTML. Тобто, це прямі ворота в пекло і його можна використовувати виключно в поєднанні з іншими бібліотеками які вміють відсікати script-и і весь не бажаний контент.

Ні, ви звісно можете сказати, що цей контент пушать наші редактори, вони точно перевірені люди, а адмін взагалі святий, але я вас попередив. Не робіть лажі.

@reactbeginners
👍111🔥1
🎁Подарунки в прямому ефірі!🎁

Як ви вже знаєте в понеділок, 03.04 о 19:00, у нас буде ефір про SOLID, про те що воно таке, навіщо воно треба і про те, чому він на React натягується, але не так щоб повністю.

❤️ А от про подарунки ви ще не знаєте. Я зібрав для вас два подарункові набори (тобто буде два переможці). Перший набір - дві пари фірмових носочків, блокнот та набір класних наліпок. Набір другий - термочашка, блокнот та теж наліпки. І ще мікросюрприз, якщо в переможця є маленька дитина. Але про це вже під час ефіру.

👉 Тож, якщо ви хочете прийняти участь в розіграші, або просто підтримати наш канал, прошу вас зробити наступне:

1️⃣ Поширити цей пост в лінкедині та написати під ним коментар. Якщо у вас немає лінкедину - нічого страшного, можете поширити його у фейсбук, твітер чи де вам зручно. Головне скиньте мені посилання на поширення, щоб я додав вас до розіграшу.

2️⃣ І, як завжди, прийти на ефір, хто не прийшов, той не отримав 😂

Чекаю на всіх, приходьте, ставте питання, будемо навчатися разом!
👍13
Сьогодні п'ятниця, тому ось вам фото подаруночків на наступний понеділок (їх насправді трохи більше, просто місця було для фото мало)

Приходьте, буде дуже лайтово, просто у форматі розмови. Мене самого колись ця тема з SOLID також діставала, тож я хочу зробити її краще ніж тоді коли вчив сам.

Неофіційний початок буде десь о 18:45, хто хоче просто поспілкуватися, приходьте трохи раніше.

Дякую за вашу підтримку і поширення (і тим хто поставив зірки на GitHub для React-Code-Smells 😁)

Всім гарної п'ятниці.
👍20❤‍🔥3
Безкоштовна практика з носіями Англійської.

❗️Мені тут підкинули ресурс, який пропонує українцям віком від 10 до 35 років (не дуже чесно, але вже як є) безкоштовну практику з англійською з носіями мови.

Не буду казати наскільки англійська важлива - це і так зрозуміло, тому кому треба англійську підтягнути (це всього година на тиждень) раджу спробувати.

❤️ Дякую Ростиславу Пилипіву за наводку.

П.С. - Чекаю всіх на 19 годину, буде SOLID, балачки та майже лисий я 😀
17👍11🤩2
Вчора у нас відбувся стрім про SOLID, наразі відео в обробці, коли буде готове я викладу сюди посилання на почищену версію.

😢 Нажаль мене вчора підвело живлення (сам винен, треба все двічі перевіряти), тому вийшло не так добре як хотілося, але я сьогодні передивився, наче не дуже погано, тому відео таки буде.

🎁 Подарунки ми також розіграли, наразі очікую лише на пані Аллу. Якщо ви це читаєте - будь-ласка відпишіть мені в Лінкедин, щоб я міг відправити переможцям подарунки. Супер приз в мене так ніхто і не забрав, значить розіграємо наступного разу 😎

❤️ Всім дякую хто прийшов, шерив та приймав учать в обговоренні.


До наступних зустрічей!
👍374
Розбираємо реальний кейс, або косячать усі.

✍️ Трохи контексту: Вечір, п'ятниця, я дуже хочу закінчити функціонал і викласти його на ремоут. Завдання дуже просте - виставити юзеру статус (затверджений, відмовлений), оновити його на бекенді, і після цього оновити UI з новим статусом.

😮‍💨 Вирішуючи трохи зекономити, я роблю ось такий, дуже простий код оновлення UI.

updateUser(user)
.then(() => {
const user = allUsers.find((x) => x.id === userId);
user.status = status;
setUsers([...allUsers]);
})
.catch(e=> {/*тут все ОК*/});

Під час тестування код чудово працює, але вже наступного дня цей код було перероблено. Як ви думаєте, чому?

Зверніть увагу, що код відпрацював на тестуванні коректно.

Перший косяк знайдено, шукаємо другий)
🤔10
Free React For Beginners
Розбираємо реальний кейс, або косячать усі. ✍️ Трохи контексту: Вечір, п'ятниця, я дуже хочу закінчити функціонал і викласти його на ремоут. Завдання дуже просте - виставити юзеру статус (затверджений, відмовлений), оновити його на бекенді, і після цього…
Давайте розбиратися:

1️⃣ Першу помилку ви знайшли швидко: використання теоретично застарілого user-а з фронтенду, замість того щоб отримати його з бекенду після апдейту.

Це може бути проблемою, коли ми оновлюємо одне поле в об'єкті, але не оновлюємо інші, залежні від нього поля (наприклад тому що правила по яким треба перерахувати залежні поля, знає лише бекенд). В результаті ми отримаємо не коректний стан даних на фронтенді, ще й розсинхронізований з бекендом.

2️⃣ Другу помилку краще проілюструвати:

export default function App() {
const [users, setUsers] = useState([{ name: "1" }]);
const updateFirstUser = () => {
users[0].name = "updated";
setUsers([...users]);
};

return (
<>
{users.map((u, i) => (
<User user={u} key={i} />
))}

<button onClick={updateFirstUser}>Update first user</button>
</>
);
}

const User = ({ user }) => <p>name: {user.name}</p>;

Якщо ви запустите цей код, то все відпрацює нормально, і по кліку на кнопку ви побачите нове ім'я користувача на сторінці. Але, якщо ви використаєте memo для компоненту User, або заміните його на PureComponent, то ваш код, несподівано, перестане працювати!

Причина полягає в тому, що, хоча екземпляр масиву змінився, але екземпляр самого об'єкту юзер - ні! Відповідно, React, порівнюючи поточний і попередній пропси (а для не примітивних типів він робить це за посиланням) буде думати що нічого не змінилося і не перемалює ваш компонент.

І якщо першу проблему, ви, скоріше за все побачите відносно швидко, то друга є геть не очевидною і може принести вашому колезі трохи болю та страждань.

Висновок:

👉 Думайте як ваш код буде використовуватися в майбутньому,
👉 Робіть паузу для саморев'ю
👉 Не спішіть в п'ятицю :)

Всім гарного вечора!
👍242
Web Vulnerabilities #3 - XSS підсумки.

👉 XSS - це виконання стороннього, не авторизованого коду на веб сторінці.

👉 XSS виникає коли ви виводити сторонню інформацію "як є", без знешкодження.

👉 Для запобігання XSS потрібно знешкоджувати будь-який сторонній контент перед додаванням його на вашу веб сторінку.

Детальніше тут і тут.

Питання до спільноти - хто хоче практичне заняття з XSS? :)

@reactbeginners
15👍11🏆1
🤯5😁1
Free React For Beginners
Photo
Ще один реальний кейс і порушення SOLID

👩‍🏫 В HTML5 є чудовий компонент -
<input type="time"/> 
який з коробки дозволяє вам досить зручно вибрати час.

👆 Але час це не просто, хоча б тому що формат його відображення різниться від країни до країни. Ми, наприклад, звикли до 24 годинного формату, а, от американцям ближче AM/PM формат часу.

💡 Тому, щоб зробити цей компонент зручним для всіх, розробники вирішили, що формат часу буде динамічно отримуватися в залежності від ваших налаштувань в ОС.

🧐 Здавалося б все чудово, але розробники забули/забили на OpenClosed принцип і захардкодили сам механізм вибору форматування. Тепер, якщо в мене стоїть англійська локаль в ОС - я бачу AM/PM і програмно змінити це не можливо. Відповідно я змушений викинути цей зручний компонент (який ще й працює з коробки в мобільних) і шукати щось нове.

🤨 Отаке, порушення одного маленького принципу, "яке потрібно лише тим хто кодить на Angular або Vanilla JS" викинуло працю кількох розробників на вітер і змусило всіх інших витрачати додатковий час на пошук та встановлення іншого рішення.

Всім гарної п'ятниці і не забивайте на такі "не потрібні" принципи програмування як SOLID.
👍232🤯1
📅 Апдейт на тиждень 📅

👩‍🏫 Працюю над відео про структуру React проекту. Спробуємо розібрати що не так у дефолтній структурі NextJS, чому і як краще. Тема суперечлива, але як казав класик, "будемо полемізувати".

🧑‍💻 Один з підписників підкинув мені цікавий кейс з реального життя, треба його вам показати. Це, скоріше за все, буде вже текстом.

❤️ Ще сьогодні буде дуже неочікуваний, але дуже крутий анонс про ще одного з членів нашого ком'юніті. Ні, в цей раз не про React, але про дещо не менш цікаве, ще й з моторчиками.

Всім гарного понеділка!
👍269
🎉 Ви не повірите, але один з наших підписників відкрив свою школу FPV пілотів! 🎉

Ну то й що скажете ви, велике діло! І, так, в звичайних умовах я б може так не радів. Але тут є декілька але.

🛫 По-перше, пілоти FPV зараз потрібні. Пілотувати Mavic або Matrice не дуже складно. Автокорекція та інтелектуальне керування все дуже спрощують. Але, з чимось більш складним (та сама Лелека), або FPV таким пілотам впоратися важче. А пілоту FPV - ні, тому що це певно найскладніший коптер для керування. Тож, якщо ви полетіли на ньому, то і на всьому іншому полетите.

💶 По-друге, це бізнес в умовах війни. Скажу чесно, зараз я радію будь-якому бізнесу, який інвестує гроші. Це зарплата, це стимуляція економіки, це розвиток. Хай навіть і в мікро дозах, але це те що зараз дуже потрібно.

❤️ Ну і по-третє - це все зробив один з нас! Навіть дизайн сайту був зроблений ще одним з членів нашого маленького ком'юніті. Ну як тут не радіти?

👉 Отже до справи. 2 - 4 людини в групі (чим менше тим краще, тож це дуже добре), тиждень симулятора, тиждень польотів. Новенька техніка, декілька варіантів FPV платформ. Плюс, за бажанням для вас можуть зібрати дрон, або, що краще, допомогти зібрати самому. Для своїх є знижка в 10% за промокодом FreeReact (на перші 5 людей)

Сайт, Інста (невже я пишу це слово), телеграм для зв'язку. Підписуйтесь (звісно кому цікаво) та поширюйте. Це дійсно корисна для всіх справа!

Серденьок йому бажаю я!
👍298
Ось ще один приклад з життя (максимально спрощений)

🗒 Маємо компонент який тримає в собі стейт моделі і керує діалогом з формою. Модель виконана у вигляді масиву об'єктів із value в середині, методу оновлення стейту немає взагалі.

export default function App() {
const [isOpen, setIsOpen] = useState(false);
const [fields] = useState([{ value: "test" }]);
const closeDialog = () => setIsOpen(false);
const openDialog = () => setIsOpen(true);

return (
<>
<button onClick={openDialog}>Open edit dialog</button>
<dialog open={isOpen}>
<Form initialFields={fields} onCancel={closeDialog} />
</dialog>
</>
);
}

🗒 Маємо другий компонент - форму, яка, приймає початкові дані і тримає їх у власному, окремому, стейті. На формі є кнопка з типом reset, яка при натисканні очищує форму та закриває діалог.

function Form({ initialFields, onCancel }) {
const [fields, setFields] = useState(initialFields);
const setField = (e, field) => {
field.value = e.target.value;
setFields([...fields]);
};
return (
<form>
{fields.map((field, i) => (
<input key={i} value={field.value} onChange={(e) => setField(e, field)} />
))}
<button type="reset" onClick={onCancel}>
Cancel
</button>
</form>
);
}

Проблема (вибачте, виклик!) полягає в тому, що, якщо ви відредагуєте поле і закриєте форму, а потім її знову відкриєте, то побачити внесені зміни. Незважаючи на reset і не зважаючи що метод setFields батьківскього компоненту взагалі не існує.

В задачі питається: де баг і що треба зробити з розробником цієї диверсії

П.С. Дякую пану Ярославу за наведений приклад.
👍10
Free React For Beginners
Ось ще один приклад з життя (максимально спрощений) 🗒 Маємо компонент який тримає в собі стейт моделі і керує діалогом з формою. Модель виконана у вигляді масиву об'єктів із value в середині, методу оновлення стейту немає взагалі. export default function…
Відповідь на попередню задачу

Попередній приклад є React версією дуже популярного на співбесіді питання, в якому початківці бувають помиляються:

const a = { v:1 };
const b = a;
b.v = 0;
console.log(a.v); // ????


Подумайте хвильку, що буде в консолі?

А в моєму прикладі все те саме, лише загорнуте в React. Тож давайте цей приклад розберемо

1️⃣ Під час першого рендеру, ми викликаємо App і передаємо в стейт масив об'єктів, а потім, одразу ж, отримаємо цей масив назад і записуємо в константу fields.

2️⃣ Після цього викликається компонент Form який отримує посилання на той самий масив через пропс і кладе отримане посилання собі в стейт. Зверніть увагу, що і в App, і в Form ми маємо один і той самий масив з тими самими об'єктами.

3️⃣ Після зміни інпуту, викликається метод SetField, який записує значення в поле value об'єкту. Потім створюється новий масив, який записується в стейт Form. Але цей новий масив все ще містить ті самі об'єкти які він отримав від компоненту App. Тому, змінюючи їх в одному місці, вони змінюються усюди.

😊От і вся магія, як бачите нічого складного. Саме тому, доречі, я рекомендую спочатку гарно розібрати JS, а потім вже переходити до React, а не навпаки.

🔨 Шляхів вирішити цю ідею - багато. Наприклад не мутувати стейт, про що книжка пише з самого початку. Або, передавати в форму клони за допомогою structuredClone або JSON.stringify/JSON.parse.

❗️Головне те, щоб ви розуміли що відбувається і чому. І тоді вирішення проблеми знайти буде геть не складно. Ще й співбесіду буде проходити легше)

Бережіть себе, допомагайте ЗСУ, скоро побачимось!
👍17