[{"data":1,"prerenderedAt":1360},["ShallowReactive",2],{"$fcfQIhBeMkzXGr5QNW5tQ7qmTE5COFu4tGXgsBbfGRbs":3,"$fMMUdSFktwQFqMVGPrTtt3EC5yheBp7PzwIqznamFcMo":90,"$fc0LoAJgqXDLbKKd2JS_NpM4SuzBK8EycUXINSg09CKU":93,"$fM3ea55k6lKMPOTM84llDB26VSQDVVbxiQuSBFQw9P_c":98,"$f1Prj1xEczHja_-L7FyIGgRHd5_cSWHo7r6AE5aheAik":443,"$fI5fDmvm-5tr9wcH0eHaKZa1j3y_FQIQaHHPqbZxAHJE":665,"mdc-ujxgsl-key":685,"mdc--5yftz1-key":697,"mdc-nxvngd-key":706,"mdc-3w7p74-key":724,"mdc-dw01og-key":733,"mdc--ug85lu-key":741,"mdc--arkl9m-key":758,"mdc-75zh0v-key":839,"mdc-i22dmw-key":939,"mdc--g4phci-key":976,"mdc-6lf49u-key":984,"mdc-l5wtqw-key":1016,"mdc-ig7eqc-key":1076,"mdc-bahewp-key":1084,"mdc-ipeuo7-key":1168,"mdc-8tjrzf-key":1177,"mdc-drral6-key":1344},{"content":4,"quizQuestionContent":60,"type":79,"pageMeta":80},[5,9,13,16,20,24,27,30,34,37,40,44,47,50,54,57],{"id":6,"value":7,"isTypeH1":8},"1908","Авторизация на сайте: cookies, токены, OAuth",true,{"id":10,"value":11,"anchor":12,"isTypeH2":8},"4382","Теория: аутентификация и авторизация","authentication-and-authorization",{"id":14,"value":15,"isTypeParagraph":8},"10087","В веб-разработке важно различать два близких понятия. Аутентификация отвечает на вопрос «кто это?», а авторизация — «что этому разрешено делать?».\n\nВ учебных вопросах словом «авторизация» часто называют именно процесс входа, то есть проверку личности, и последующее поддержание состояния «пользователь вошёл». Поскольку HTTP-запросы сами по себе не содержат «памяти о прошлом», серверу требуется получать при каждом запросе некоторый идентификатор или доказательство того, что запрос выполняется от имени конкретного пользователя.\n\nОтсюда возникает практическая задача: после успешного входа необходимо «привязать» дальнейшие запросы к пользователю, чтобы сервер мог:\n- Узнать пользователя.\n- Проверить срок действия входа.\n- Проверить права (роль, доступ к конкретным ресурсам).",{"id":17,"description":18,"titleAlert":19,"isTypeAlertInfo":8},"643","В реальном проекте почти всегда присутствуют две части: (1) способ доставки «доказательства входа» в каждом запросе и (2) серверная проверка этого доказательства при доступе к защищённым данным.",null,{"id":21,"value":22,"anchor":23,"isTypeH2":8},"4383","Сессионные cookie (сервер хранит сессию)","session-cookies",{"id":25,"value":26,"isTypeParagraph":8},"10088","Cookie — это небольшой фрагмент данных, который сервер отправляет браузеру, а браузер затем автоматически отправляет обратно этому же сайту в последующих запросах.\n\nТипичный сценарий:\n1) Пользователь отправляет логин/пароль на `/login`.\n2) Сервер проверяет данные и создаёт запись сессии на своей стороне (например, в памяти, Redis, базе данных).\n3) Сервер отправляет cookie с идентификатором сессии (например, `sid=...`).\n4) Браузер автоматически прикрепляет cookie к следующим запросам, а сервер по `sid` находит сессию и понимает, кто выполняет запрос.\n\nПример (упрощённо): создание сессии и установка cookie\n```\n// Псевдокод: идея одинакова во многих языках/фреймворках\n\nPOST /login\n-> проверить пароль\n-> sessionId = random()\n-> sessions[sessionId] = { userId: 123, createdAt: now(), expiresAt: now()+... }\n-> ответ:\n   Set-Cookie: sid=sessionId; HttpOnly; Secure; SameSite=Lax\n   200 OK\n\nGET /profile\n(браузер автоматически отправляет Cookie: sid=sessionId)\n-> сервер читает sid\n-> находит sessions[sid]\n-> если найдено и не истекло, отдаёт страницу/JSON\n```\n\nЗачем серверное хранилище сессий удобно:\n- Можно быстро «отозвать» вход: достаточно удалить сессию на сервере.\n- Можно хранить дополнительные признаки (например, время входа, устройство, CSRF-токен, флаги безопасности).\n- Можно централизованно применять правила (ограничение по времени, принудительный выход).\n",{"id":28,"description":29,"titleAlert":19,"isTypeAlertWarning":8},"703","Если злоумышленник получит значение cookie с идентификатором сессии, может возникнуть захват сессии. Поэтому важны HTTPS и корректные атрибуты cookie (например, `HttpOnly`, `Secure`, `SameSite`) и защита от XSS.",{"id":31,"value":32,"anchor":33,"isTypeH2":8},"4384","Токены и заголовок Authorization: Bearer","bearer-tokens",{"id":35,"value":36,"isTypeParagraph":8},"10089","Токенный подход означает, что клиент хранит токен и отправляет его с каждым запросом к защищённому API. Часто токен передаётся в заголовке авторизации: `Authorization: Bearer ...`.\n\nЭто описано в спецификациях семейства OAuth 2.0 (например, RFC 6750 для Bearer Token Usage), где задаётся стандартный формат передачи токена, включая пример заголовка `Authorization: Bearer \u003Ctoken>`.\n\nПример HTTP-запроса с Bearer-токеном\n```\nGET /api/orders HTTP/1.1\nHost: example.com\nAuthorization: Bearer eyJhbGciOi...\n```\n\nПример серверной проверки (упрощённо)\n```\nfunction authMiddleware(req):\n  header = req.headers[\"authorization\"]\n\n  if header is missing:\n    return 401\n\n  if not header startsWith \"Bearer \":\n    return 401\n\n  token = header after \"Bearer \"\n  claims = verifyAndDecode(token) // подпись, срок действия, аудитория и т.п.\n\n  if claims invalid:\n    return 401\n\n  req.userId = claims.sub\n  return next()\n```\n\nОсобенность Bearer-токена: «кто владеет токеном, тот и проходит проверку». Поэтому утечка токена обычно равна утечке доступа на время жизни токена, и требуется строго защищать каналы передачи (TLS) и место хранения.",{"id":38,"description":39,"titleAlert":19,"isTypeAlertWarning":8},"704","Для токенов важно продумывать срок жизни и отзыв. Если токен долгоживущий и его сложно отозвать, последствия утечки становятся значительно тяжелее.",{"id":41,"value":42,"anchor":43,"isTypeH2":8},"4385","OAuth 2.0 (федеративный вход)","oauth2",{"id":45,"value":46,"isTypeParagraph":8},"10090","OAuth 2.0 — это стандарт, описывающий делегирование доступа: клиентское приложение получает токен доступа к ресурсам от сервера авторизации. В сценарии «вход через провайдера» (например, через отдельный аккаунт-провайдер) OAuth 2.0 часто используется совместно со стандартами, которые добавляют «слой идентичности» (например, OpenID Connect).\n\nОдин из распространённых потоков — Authorization Code:\n1) Клиент перенаправляет браузер пользователя на endpoint авторизации.\n2) Пользователь аутентифицируется на стороне сервера авторизации и подтверждает согласие.\n3) Сервер авторизации перенаправляет браузер обратно на сайт клиента с параметром `code`.\n4) Сервер клиента (или доверенный backend) обменивает `code` на `access_token` (и иногда `refresh_token`).\n5) Далее запросы к API выполняются с предъявлением токена.\n\nСхема (упрощённо) Authorization Code Flow\n```\nПользователь -> Клиент (сайт) -> Сервер авторизации -> Клиент -> Ресурсный сервер\n\n1) Клиент: redirect на /authorize\n2) Сервер авторизации: вход + согласие\n3) Redirect обратно: ?code=...\n4) Клиент: POST /token (обмен code на access_token)\n5) Клиент/приложение: запросы к API с access_token\n```",{"id":48,"description":49,"titleAlert":19,"isTypeAlertInfo":8},"644","Смысл федеративной схемы в том, что пароль пользователя не передаётся стороннему сайту: ввод учётных данных происходит только на стороне сервера авторизации.\n",{"id":51,"value":52,"anchor":53,"isTypeH2":8},"4386","Почему DNS, CSS/HTML и CDN-кэш — не авторизация","why-not-dns-css-cdn",{"id":55,"value":56,"isTypeParagraph":8},"10091","DNS:\nDNS решает задачу именования (как по доменному имени находить нужные сетевые параметры), но не содержит модели «конкретный пользователь вошёл в систему» и не обеспечивает проверку прав на уровне запросов к веб-приложению.\n\nCSS/HTML:\nCSS описывает внешний вид (оформление), HTML — структуру документа. Эти технологии не предназначены для криптографической проверки личности и не дают серверу проверяемого доказательства, что запрос сделан именно конкретным пользователем.\n\nCDN-кэш:\nCDN занимается доставкой и кэшированием. Кэш может хранить и повторно выдавать ответы, но это не является подтверждением личности. Наоборот, при неправильных настройках кэша возможно случайное распространение приватного контента, поэтому приватные страницы обычно помечаются так, чтобы кэширование происходило безопасно (или не происходило вовсе), а доступ контролировался cookie/токенами на сервере.\n\nТаблица: чем отличаются подходы\n| Подход | Что отправляется в каждом запросе | Где хранится «состояние входа» | Типичный плюс | Типичный риск/сложность |\n|---|---|---|---|---|\n| Сессионные cookie | `Cookie: sid=...` (автоматически браузером) | На сервере (сессия по `sid`) | Удобно для классических сайтов, легко отзывать сессию | Риски при XSS/угоне cookie, важны атрибуты безопасности |\n| Bearer-токен | `Authorization: Bearer ...` | Часто «внутри» токена и/или в системе проверки | Удобно для API и разных клиентов | Утечка токена обычно даёт доступ, важны срок жизни и отзыв |\n| OAuth 2.0 | После получения — предъявление access token | Сервер авторизации выдаёт токены, ресурсный сервер проверяет | Делегирование доступа, пароль не передаётся клиенту | Больше компонентов и настроек, важны redirect URI и безопасность потока |",{"id":58,"value":59,"isTypeParagraph":8},"10092","Итого: авторизация (в смысле «вход и поддержание состояния входа») обычно реализуется через сессионные cookie или через токены (например, `Authorization: Bearer ...`), а для входа через внешнего провайдера применяется OAuth 2.0; DNS, CSS/HTML и CDN-кэш не предназначены для подтверждения личности пользователя.",{"id":61,"options":62,"hint":76,"solution":77,"description":78},"1147",[63,67,70,73],{"id":64,"label":65,"isCorrect":66},"4733","Авторизация на сайте протекает только через DNS-записи домена, так как DNS определяет права пользователя  ",false,{"id":68,"label":69,"isCorrect":8},"4734","Авторизация может протекать через сессионные cookie (сервер хранит сессию) или через токены (клиент отправляет `Authorization: Bearer ...`), а также через федеративные схемы вроде OAuth/OIDC  ",{"id":71,"label":72,"isCorrect":66},"4735","Авторизация выполняется исключительно с помощью CSS и HTML, потому что стили и разметка подтверждают личность  ",{"id":74,"label":75,"isCorrect":66},"4736","Авторизация происходит за счёт кэширования страниц на CDN: если страница в кэше, пользователь считается вошедшим","Правильным является вариант, где описан механизм, который сервер может проверять при каждом запросе: cookie/сессия или токен в `Authorization`, а также федеративные протоколы (OAuth). DNS, CSS/HTML и CDN-кэш не предоставляют серверу проверяемого доказательства личности пользователя.","**Правильный ответ: 2** - Авторизация может протекать через сессионные cookie (сервер хранит сессию) или через токены (клиент отправляет `Authorization: Bearer ...`), а также через федеративные схемы вроде OAuth/OIDC  \n\nРазбор вариантов\n1) Неверно: DNS предназначен для работы с доменными именами и ресурсными записями (например, чтобы по имени находить адрес сервера), но не определяет личность пользователя и не задаёт его права на сайте.\n\n2) Верно: авторизация (в учебных задачах часто имеется в виду «вход и поддержание состояния входа») обычно выполняется:\n- Через сессионные cookie: браузер хранит cookie, сервер хранит сессию.\n- Через токены: клиент отправляет токен в заголовке `Authorization: Bearer ...`.\n- Через федеративные схемы: OAuth 2.0 (часто вместе с OpenID Connect для «входа через провайдера»).\n\n3) Неверно: CSS и HTML отвечают за представление и структуру страницы, но не являются механизмами подтверждения личности.\n\n4) Неверно: кэширование на CDN ускоряет выдачу контента, но не подтверждает личность и не должно «делать пользователя вошедшим». Более того, ошибки кэширования приватных страниц могут приводить к утечкам данных.","Каким способом может выполняться авторизация пользователя на сайте?","quizQuestion",{"title":81,"description":82,"ogTitle":81,"ogDescription":82,"ogImageUrl":83,"canonical":19,"ogLocale":84,"ogSiteName":85,"ogImageType":86,"ogImageWidth":87,"ogImageHeight":88,"ogType":89,"ogUrl":19},"Способы авторизации пользователя на сайте","Разбор сессий, токенов, OAuth/OIDC, MFA и практик безопасности.","/og-image.png","ru_RU","goodwebjob.ru","image_jpeg","1200","630","article",{"siteName":91,"siteUrl":92},"GOOD WEB JOB!","https://goodwebjob.ru",[94],{"label":95,"slug":96,"to":97},"Подготовка к тех.интервью","technical-interview","/technical-interview/where-to-begin",{"navigationList":99,"navigationSublist":107},[100,103],{"path":97,"isActive":66,"name":101,"icon":102,"isNavbarMobileDisabled":8},"С чего начать?","material-symbols:visibility-outline-rounded",{"path":104,"isActive":8,"name":105,"icon":106,"isNavbarMobileDisabled":66},"/technical-interview/tasks","Сборник задач","material-symbols:task-outline",[108,117,144,156,162,303,327,336,342,404,425,431],{"title":109,"list":110,"isOpened":66},"Bash",[111,114],{"name":112,"path":113,"isActive":66},"Дан фрагмент bash-скрипта: cd ~; mkdir foo... Что в нем происходит?","/technical-interview/tasks/here-is-a-fragment-of-a-bash-script-cd-mkdir-foo-what-is-happening-in-this-script",{"name":115,"path":116,"isActive":66},"Дан фрагмент bash-скрипта: target=$(ps -Af | grep $1 | head -n 1)...","/technical-interview/tasks/here-is-a-fragment-of-a-bash-script-target-ps-af-grep-1-head-n-1",{"title":118,"list":119,"isOpened":66},"CSS",[120,123,126,129,132,135,138,141],{"name":121,"path":122,"isActive":66},"Дан HTML-код. Какой будет цвет у текста «Some dummy text»?","/technical-interview/tasks/the-html-code-is-given-what-will-be-the-color-of-the-some-dummy-text",{"name":124,"path":125,"isActive":66},"Есть шаблон HTML и CSS кода. Какой будет цвет у текста «Таким образом, постоянное»?","/technical-interview/tasks/there-is-a-template-for-html-and-css-code-what-color-will-the-text-thus-constant-have",{"name":127,"path":128,"isActive":66},"Есть шаблон вложенного HTML кода. Какой будет цвет у текста «One more dummy text»?","/technical-interview/tasks/there-is-a-template-for-embedded-html-code-what-will-be-the-color-of-the-one-more-dummy-text",{"name":130,"path":131,"isActive":66},"Есть шаблон вложенного HTML кода. Будет ли display:block у body влиять на span?","/technical-interview/tasks/there-is-a-template-for-embedded-html-code-will-there-be-a-display-does-bodys-block-affect-span",{"name":133,"path":134,"isActive":66},"Есть HTML код. Будет ли font-weight на span влиять?","/technical-interview/tasks/there-is-an-html-code-will-font-weight-affect-span",{"name":136,"path":137,"isActive":66},"Flexbox и Grid, чем отличаются друг от друга?","/technical-interview/tasks/what-are-the-differences-between-flexbox-and-grid",{"name":139,"path":140,"isActive":66},"Заменяют ли Flexbox и Grid друг друга?","/technical-interview/tasks/do-flexbox-and-grid-replace-each-other",{"name":142,"path":143,"isActive":66},"Есть CSS и JS анимация. Какая между ними разница, что быстрее, что более удобно?","/technical-interview/tasks/there-are-css-and-js-animations-what-is-the-difference-between-them-and-which-is-faster-and-more-convenient",{"title":145,"list":146,"isOpened":66},"Git",[147,150,153],{"name":148,"path":149,"isActive":66},"Разрабатывал, взял закоммитил, запушил. Оказалось, что запушил не в ту ветку, точнее, коммит не в ту ветку. Какие действия?","/technical-interview/tasks/developed-it-committed-it-and-launched-it-it-turned-out-that-i-had-pushed-it-to-the-wrong-branch-or-rather-the-commit-was-in-the-wrong-branch-what-actions",{"name":151,"path":152,"isActive":66},"В git есть несколько вариантов слияния веток, какие? Чем отличаются?","/technical-interview/tasks/git-has-several-options-for-merging-branches-which-ones-how-are-they-different",{"name":154,"path":155,"isActive":66},"Какие существуют стратегии ветвления для работы команды? Что это такое?","/technical-interview/tasks/what-are-the-branching-strategies-for-the-team-what-is-it",{"title":157,"list":158,"isOpened":66},"HTML",[159],{"name":160,"path":161,"isActive":66},"Что такое HTML?","/technical-interview/tasks/what-is-html",{"title":163,"list":164,"isOpened":66},"JavaScript",[165,168,171,174,177,180,183,186,189,192,195,198,201,204,207,210,213,216,219,222,225,228,231,234,237,240,243,246,249,252,255,258,261,264,267,270,273,276,279,282,285,288,291,294,297,300],{"name":166,"path":167,"isActive":66},"Какие логические значения в console.log будут получены?","/technical-interview/tasks/prototype-what-logical-values-will-be-received-in-console-log",{"name":169,"path":170,"isActive":66},"Почему опасно писать прямо в прототипы базовых типов?","/technical-interview/tasks/why-is-it-dangerous-to-write-directly-to-the-prototypes-of-basic-types",{"name":172,"path":173,"isActive":66},"Что вернёт следующий код? Object.create(null).hasOwnProperty('toString')","/technical-interview/tasks/what-will-the-following-code-return-object-create-null-has-own-property-to-string",{"name":175,"path":176,"isActive":66},"Какое значение выведет консоль с object.property?","/technical-interview/tasks/what-value-will-the-console-output-with-object-property",{"name":178,"path":179,"isActive":66},"Что выведется в console.log([arr[0](), arr[0]()])?","/technical-interview/tasks/what-will-be-displayed-in-console-log-arr-0-arr-0",{"name":181,"path":182,"isActive":66},"Что выведет console.log в результате выполнения цикла while?","/technical-interview/tasks/what-will-console-log-output-as-a-result-of-executing-the-while-loop",{"name":184,"path":185,"isActive":66},"Есть функция и объект. Напишите все известные вам способы, чтобы вывести в консоли значение x из объекта, используя функцию","/technical-interview/tasks/there-is-a-function-and-an-object-write-all-the-ways-you-know-to-output-the-value-of-x-from-an-object-in-the-console-using-the-function",{"name":187,"path":188,"isActive":66},"Что вернёт метод book.getUpperName()?","/technical-interview/tasks/what-will-the-book-get-upper-name-method-return",{"name":190,"path":191,"isActive":66},"Переменные объявлены следующим образом: a=3; b=«hello»;. Укажите правильное утверждение","/technical-interview/tasks/variables-are-declared-as-follows-specify-the-correct-statement",{"name":193,"path":194,"isActive":66},"Что выведет консоль в случае присвоения свойства массиву по строковому положительному индексу?","/technical-interview/tasks/what-will-the-console-display-if-a-property-is-assigned-to-an-array-using-a-positive-string-index",{"name":196,"path":197,"isActive":66},"Что выведет консоль в случае присвоения свойства массиву по строковому отрицательному индексу?","/technical-interview/tasks/what-will-the-console-display-if-a-property-is-assigned-to-an-array-using-a-negative-string-index",{"name":199,"path":200,"isActive":66},"Что выведет консоль в случае удаления элемента массива с помощью оператора delete?","/technical-interview/tasks/what-will-the-console-output-if-an-array-element-is-deleted-using-the-delete-operator",{"name":202,"path":203,"isActive":66},"Что вернёт этот код: typeof (function(){})()","/technical-interview/tasks/what-this-code-will-return-typeof-function",{"name":205,"path":206,"isActive":66},"Что получится в результате передачи объекта как аргумента в функцию и выполнения кода?","/technical-interview/tasks/what-will-happen-when-an-object-is-passed-as-an-argument-to-a-function-and-the-code-is-executed",{"name":208,"path":209,"isActive":66},"Какие способы объявления функции есть в JavaScript?","/technical-interview/tasks/what-are-the-ways-to-declare-a-function-in-javascript",{"name":211,"path":212,"isActive":66},"Что такое this в JavaScript?","/technical-interview/tasks/what-is-this-in-javascript",{"name":214,"path":215,"isActive":66},"Что такое Event Loop, как работает?","/technical-interview/tasks/what-is-an-event-loop-and-how-does-it-work",{"name":217,"path":218,"isActive":66},"Что будет, если вызвать typeof на необъявленной переменной?","/technical-interview/tasks/what-happens-if-you-call-typeof-on-an-undeclared-variable",{"name":220,"path":221,"isActive":66},"Что показывает оператор typeof в JavaScript?","/technical-interview/tasks/what-does-the-typeof-operator-show-in-javascript",{"name":223,"path":224,"isActive":66},"Какие типы данных существует в JavaScript?","/technical-interview/tasks/what-types-of-data-exist-in-javascript",{"name":226,"path":227,"isActive":66},"Какую структуру использовать для хранения упорядоченного списка строк в JavaScript?","/technical-interview/tasks/what-is-the-best-structure-to-use-for-storing-an-ordered-list-of-strings-in-javascript",{"name":229,"path":230,"isActive":66},"Что вернет typeof для массива?","/technical-interview/tasks/what-will-typeof-return-for-an-array",{"name":232,"path":233,"isActive":66},"Почему оператор typeof, применённый к массиву, возвращает объект?","/technical-interview/tasks/why-does-the-typeof-operator-applied-to-an-array-return-an-object",{"name":235,"path":236,"isActive":66},"Если нужно хранить список уникальных строк, какую структуру данных выбрать?","/technical-interview/tasks/if-you-need-to-store-a-list-of-unique-strings-which-data-structure-should-i-choose",{"name":238,"path":239,"isActive":66},"Что возвращает typeof для new Set в JavaScript?","/technical-interview/tasks/what-does-typeof-return-for-new-set-in-javascript",{"name":241,"path":242,"isActive":66},"Почему в JavaScript два объекта с одинаковым содержимым при сравнении возвращают false?","/technical-interview/tasks/why-do-two-objects-with-the-same-content-return-false-when-compared-in-javascript",{"name":244,"path":245,"isActive":66},"В чем разница между микро- и макро-тасками в JavaScript?","/technical-interview/tasks/what-is-the-difference-between-micro-and-macro-tasks-in-javascript",{"name":247,"path":248,"isActive":66},"arr.push(0) повлияет на массив так же, как если бы мы выполнили...","/technical-interview/tasks/arr-push-0-will-affect-the-array-in-the-same-way-as-if-we-performed",{"name":250,"path":251,"isActive":66},"Вернуть массив от 1 до n, где числа, кратные 3, заменены на 'fizz', кратные 5 - на 'buzz', а кратные и 3, и 5 одновременно - на 'fizzbuzz'","/technical-interview/tasks/returns-an-array-from-1-to-n-replacing-numbers-that-are-multiples-of-3-with-fizz-numbers-that-are-multiples-of-5-with-buzz-and-numbers-that-are-multiples-of-both-3-and-5-with-fizzbuzz",{"name":253,"path":254,"isActive":66},"Дана строка: 'one.two.three.four.five'. Необходимо из строки сделать вложенный объект","/technical-interview/tasks/the-string-one-two-three-four-five-is-given-it-is-necessary-to-make-a-nested-object-out-of-the-string",{"name":256,"path":257,"isActive":66},"Дано дерево (вложенный объект), надо найти сумму всех вершин","/technical-interview/tasks/given-a-tree-nested-object-it-is-necessary-to-find-the-sum-of-all-vertices",{"name":259,"path":260,"isActive":66},"Для каждого вложенного объекта нужно добавить свойство level, которое равняется числу - номер вложенности","/technical-interview/tasks/for-each-nested-object-you-need-to-add-the-level-property-which-is-equal-to-a-number-the-nesting-number",{"name":262,"path":263,"isActive":66},"Для каждой ветви дерева записать номер вложенности данной ветви","/technical-interview/tasks/for-each-branch-of-the-tree-write-down-the-nesting-number-of-this-branch",{"name":265,"path":266,"isActive":66},"Есть массив, в котором лежат объекты с датами, необходимо отсортировать даты по возрастанию","/technical-interview/tasks/there-is-an-array-containing-objects-with-dates-that-need-to-be-sorted-by-date",{"name":268,"path":269,"isActive":66},"Есть слова в массиве, необходимо определить, состоят ли они из одних и тех же букв","/technical-interview/tasks/there-are-words-in-the-array-it-is-necessary-to-determine-whether-they-consist-of-the-same-letters",{"name":271,"path":272,"isActive":66},"Есть строка, состоящая из разных скобок, необходимо проверить, закрыты ли все","/technical-interview/tasks/there-is-a-string-consisting-of-different-brackets-it-is-necessary-to-check-whether-all-are-closed",{"name":274,"path":275,"isActive":66}," Найти в массиве неповторяющиеся числа","/technical-interview/tasks/find-non-repeating-numbers-in-an-array",{"name":277,"path":278,"isActive":66},"Напишите функцию, который сделает из массива объект","/technical-interview/tasks/write-a-function-that-will-make-an-object-out-of-an-array",{"name":280,"path":281,"isActive":66},"Необходимо проверить, являются ли две строки анаграммами друг друга","/technical-interview/tasks/checks-whether-two-strings-are-anagrams-of-each-other",{"name":283,"path":284,"isActive":66},"Нечётные числа должны отсортироваться по возрастанию, а чётные должны остаться на своих местах","/technical-interview/tasks/odd-numbers-should-be-sorted-in-ascending-order-and-even-numbers-should-remain-in-their-original-positions",{"name":286,"path":287,"isActive":66},"Определить, является ли слово палиндромом","/technical-interview/tasks/determines-whether-a-word-is-a-palindrome",{"name":289,"path":290,"isActive":66},"«Расплющивание» массива","/technical-interview/tasks/flattening-the-array",{"name":292,"path":293,"isActive":66},"Реализовать функцию, принимающую аргументы \"*\", \"1\", \"b\", \"1c\" и возвращающую строку \"1*b*1c\"","/technical-interview/tasks/implement-a-function-that-accepts-arguments-1-b-1c-and-the-return-string-1-b-1c",{"name":295,"path":296,"isActive":66},"Сжатие строк","/technical-interview/tasks/string-compression",{"name":298,"path":299,"isActive":66},"Уникализация значений в массиве","/technical-interview/tasks/unifying-values-in-an-array",{"name":301,"path":302,"isActive":66},"Числа от 1 до 100 находятся в массиве, они хаотично перемешанные, но в нём не хватает одного числа из этой последовательности. Необходимо найти его","/technical-interview/tasks/the-numbers-from-1-to-100-are-in-the-array-they-are-randomly-mixed-but-it-lacks-one-number-from-this-sequence-it-is-necessary-to-find-him",{"title":304,"list":305,"isOpened":66},"React",[306,309,312,315,318,321,324],{"name":307,"path":308,"isActive":66},"Для чего нужен React, какие он решает проблемы?","/technical-interview/tasks/what-is-react-used-for-and-what-problems-does-it-solve",{"name":310,"path":311,"isActive":66},"Какой механизм лежит в основе оптимизации обновлений DOM в React?","/technical-interview/tasks/what-is-the-underlying-mechanism-for-optimizing-dom-updates-in-react",{"name":313,"path":314,"isActive":66},"Если убрать в React VDOM/Fiber, и вручную изменять DOM, разве это не оптимально?","/technical-interview/tasks/if-you-remove-the-vdom-fiber-in-react-and-manually-change-the-dom-isn-t-that-optimal",{"name":316,"path":317,"isActive":66},"Есть блок кода. Что в реальном DOM изменится после нажатия на кнопку?","/technical-interview/tasks/there-is-a-block-of-code-what-changes-in-the-real-dom-after-clicking-the-button",{"name":319,"path":320,"isActive":66},"Есть код, в котором список и кнопка. Что в реальном DOM изменится после нажатия на кнопку?","/technical-interview/tasks/there-is-a-code-in-which-there-is-a-list-and-a-button-what-will-change-in-the-real-dom-after-clicking-on-the-button",{"name":322,"path":323,"isActive":66},"Зачем нужен Redux (Mobx/Effector)? Зачем нужен менеджер состояния? Какие проблемы решает?","/technical-interview/tasks/why-do-we-need-redux-mobx-effector-why-do-we-need-a-state-manager-what-problems-does-it-solve",{"name":325,"path":326,"isActive":66},"Что мешает организовать централизованное состояние без менеджера состояния? Если организовать состояние механизмами реакта: контекстом, стейтом, в чем проблема? Что менеджеры состояния привносят?","/technical-interview/tasks/what-prevents-you-from-organizing-a-centralized-state-without-a-state-manager-if-you-organize-the-state-using-react-context-and-state-mechanisms-what-is-the-problem-what-do-state-managers-add",{"title":328,"list":329,"isOpened":66},"Алгоритмы",[330,333],{"name":331,"path":332,"isActive":66},"Что такое алгоритмическая сложность?","/technical-interview/tasks/what-is-algorithmic-complexity",{"name":334,"path":335,"isActive":66},"Какая алгоритмическая сложность у \"быстрой сортировки\"?","/technical-interview/tasks/what-is-the-algorithmic-complexity-of-quick-sort",{"title":337,"list":338,"isOpened":66},"Дебаггинг",[339],{"name":340,"path":341,"isActive":66},"Как диагностировать и исправить нежелательное изменение цвета фона по клику на кнопку, если исходный код сайта запутан и недоступен для прямого чтения?","/technical-interview/tasks/how-can-diagnose-and-fix-unwanted-background-color-changes-when-clicking-on-a-button-if-the-source-code-of-the-site-is-confusing-and-inaccessible-to-direct-reading",{"title":343,"list":344,"isOpened":66},"Компьютерные сети",[345,348,351,354,357,360,363,366,369,372,375,378,381,384,387,390,393,396,399,402],{"name":346,"path":347,"isActive":66},"Как браузер после ввода домена понимает, откуда брать сайт?","/technical-interview/tasks/how-does-the-browser-know-where-to-get-the-website-after-entering-the-domain",{"name":349,"path":350,"isActive":66},"Что такое DNS, как DNS находит нужный IP-адрес?","/technical-interview/tasks/what-is-dns-and-how-does-dns-find-the-correct-ip-address",{"name":352,"path":353,"isActive":66},"Как домен попадает в DNS в таблицу соответствия: домен – ip","/technical-interview/tasks/how-does-a-domain-get-into-the-dns-mapping-table-domain-ip",{"name":355,"path":356,"isActive":66},"Как браузер решает, какое соединение ему открывать, TCP или UDP?","/technical-interview/tasks/how-does-a-browser-decide-whether-to-open-a-tcp-or-udp-connection",{"name":358,"path":359,"isActive":66},"Ключевые отличия TCP и UDP","/technical-interview/tasks/key-differences-between-tcp-and-udp",{"name":361,"path":362,"isActive":66},"\"TCP/IP\" - кем является TCP, а кем IP в данном случае?","/technical-interview/tasks/tcp-ip-who-is-tcp-and-who-is-ip-in-this-case",{"name":364,"path":365,"isActive":66},"Что такое HTTP и из чего состоит?","/technical-interview/tasks/what-is-http-and-what-does-it-consist-of",{"name":367,"path":368,"isActive":66},"Что такое заголовки в HTTP и зачем они нужны?","/technical-interview/tasks/what-are-http-headers-and-why-do-we-need-them",{"name":370,"path":371,"isActive":66},"Что такое параметры в HTTP?","/technical-interview/tasks/what-are-http-parameters",{"name":373,"path":374,"isActive":66},"Где находится HTML-код в структуре HTTP-ответа?","/technical-interview/tasks/where-is-the-html-code-located-in-the-http-response-structure",{"name":376,"path":377,"isActive":66},"Чем отличаются 1.0, 1.1, 2.0, 3.0 версии HTTP?","/technical-interview/tasks/what-are-the-differences-between-http-versions-1-0-1-1-2-0-and-3-0",{"name":379,"path":380,"isActive":66},"Пользователь авторизован на сайте. Как сервер узнает об этом с последующими другими заходами, что «я – авторизованный пользователь»?","/technical-interview/tasks/the-user-is-logged-in-on-the-website-how-does-the-server-know-that-i-am-an-authorized-user-when-the-user-logs-in-again",{"name":382,"path":383,"isActive":66},"Что такое cookie?","/technical-interview/tasks/what-is-a-cookie",{"name":385,"path":386,"isActive":66},"Кто является инициатором записи cookie в браузере?","/technical-interview/tasks/who-initiates-the-cookie-recording-in-the-browser",{"name":388,"path":389,"isActive":66},"Есть ли возможность с клиента (с браузера) управлять cookie?","/technical-interview/tasks/is-it-possible-to-manage-cookies-from-the-client-browser",{"name":391,"path":392,"isActive":66},"Верно ли утверждение, что злоумышленник, контролирующий роутер и прослушивающий трафик, может получить логины и пароли от сайтов, на которые заходит клиент?","/technical-interview/tasks/is-it-true-that-an-attacker-who-controls-a-router-and-listens-to-traffic-can-obtain-logins-and-passwords-from-websites-that-a-client-visits",{"name":394,"path":395,"isActive":66},"Всё, что идет по HTTPS – оно защищено?","/technical-interview/tasks/is-everything-that-goes-through-https-secure",{"name":397,"path":398,"isActive":66},"Все данные зашифрованы, используется https. Хакер взламывает dns и делает подмену одного ip на другой, на фишинговый сайт. В этом случае, злоумышленник может получить данные (логин \\ пароль)?","/technical-interview/tasks/all-data-is-encrypted-https-is-used-let-s-assume-a-hacker-hacks-the-dns-and-makes-a-substitution-of-one-ip-for-another-a-phishing-site",{"name":400,"path":401,"isActive":66},"Есть веб-приложение. Помимо HTTP, какие протоколы того же уровня (Application Layer) можно дополнительно использовать в веб-приложении в браузере?","/technical-interview/tasks/there-is-a-web-application-in-addition-to-http-what-other-protocols-of-the-same-level-application-layer-can-be-used-in-the-web-application-in-browser",{"name":78,"path":403,"isActive":66},"/technical-interview/tasks/how-can-a-user-be-authorized-on-a-website",{"title":405,"list":406,"isOpened":66},"Отрисовка в браузере",[407,410,413,416,419,422],{"name":408,"path":409,"isActive":66},"Что происходит, когда HTTP прислал HTML? Что браузер дальше делает c HTML с учетом того, что она валидная?","/technical-interview/tasks/what-happens-when-http-sends-html-what-does-the-browser-do-with-this-html-given-that-it-is-valid",{"name":411,"path":412,"isActive":66},"Как браузер парсит JavaScript и изображения при рендеринге?","/technical-interview/tasks/how-the-browser-parses-javascript-and-images-when-rendering",{"name":414,"path":415,"isActive":66},"Что в браузере блокирует рендеринг страницы?","/technical-interview/tasks/what-is-blocking-the-page-rendering-in-the-browser",{"name":417,"path":418,"isActive":66},"Что такое DOM в браузере? Что такое CSSOM?","/technical-interview/tasks/what-is-dom-in-a-browser-what-is-cssom",{"name":420,"path":421,"isActive":66},"Что является узлами в DOM?","/technical-interview/tasks/what-are-nodes-in-the-dom",{"name":423,"path":424,"isActive":66},"Из чего состоит CSSOM?","/technical-interview/tasks/what-does-cssom-consist-of",{"title":426,"list":427,"isOpened":66},"Ревью кода",[428],{"name":429,"path":430,"isActive":66},"По каким характеристикам, ревьюер понимает, что данный код - хороший, а этот код - плохой?","/technical-interview/tasks/how-does-a-reviewer-know-which-code-is-good-and-which-code-is-bad",{"title":432,"list":433,"isOpened":66},"Теория вероятности",[434,437,440],{"name":435,"path":436,"isActive":66},"В комнате три человека. Какова вероятность того, что хотя бы двое из них одного пола? То есть два и более.","/technical-interview/tasks/there-are-three-people-in-the-room-what-is-the-probability-that-at-least-two-of-them-are-of-the-same-sex-that-is-two-or-more",{"name":438,"path":439,"isActive":66},"Есть монета. Ее подбрасывают пять раз подряд. Каждый раз записывается, что выпало - орел или решка. Сколько разных последовательностей орлов и решек может при этом получиться?","/technical-interview/tasks/there-is-a-coin-it-is-tossed-five-times-in-a-row-each-time-it-is-recorded-whether-it-lands-on-heads-or-tails-how-many-different-sequences-of-heads-and-tails-can-be-obtained",{"name":441,"path":442,"isActive":66},"Как гарантированно найти лёгкую фальшивую монету среди 8 за минимальное число взвешиваний на чашечных весах?","/technical-interview/tasks/how-can-you-guarantee-to-find-an-easy-fake-coin-among-8-in-the-minimum-number-of-weighings-on-a-balance-scale",{"slugs":444},[445,448,450,452,454,457,460,462,464,466,468,470,473,475,477,479,481,483,485,487,489,491,493,495,497,499,501,503,505,507,509,511,513,515,517,519,521,523,525,527,529,531,533,535,537,539,541,543,545,547,549,551,554,556,558,560,562,564,566,568,570,572,574,576,578,580,582,584,586,588,590,592,594,596,598,600,602,604,606,608,610,612,614,616,618,620,622,624,626,628,630,632,634,636,638,640,642,644,646,648,650,652,654,655,657,659,661,663],{"name":446,"value":447},"Теоретические задания","theoretical-tasks",{"name":202,"value":449},"what-this-code-will-return-typeof-function",{"name":101,"value":451},"where-to-begin",{"name":169,"value":453},"why-is-it-dangerous-to-write-directly-to-the-prototypes-of-basic-types",{"name":455,"value":456},"Backend","backend",{"name":458,"value":459},"Frontend","frontend",{"name":166,"value":461},"prototype-what-logical-values-will-be-received-in-console-log",{"name":283,"value":463},"odd-numbers-should-be-sorted-in-ascending-order-and-even-numbers-should-remain-in-their-original-positions",{"name":274,"value":465},"find-non-repeating-numbers-in-an-array",{"name":247,"value":467},"arr-push-0-will-affect-the-array-in-the-same-way-as-if-we-performed",{"name":253,"value":469},"the-string-one-two-three-four-five-is-given-it-is-necessary-to-make-a-nested-object-out-of-the-string",{"name":471,"value":472},"Реализовать функцию, похоже как в Jquery","implement-a-function-similar-to-jquery",{"name":259,"value":474},"for-each-nested-object-you-need-to-add-the-level-property-which-is-equal-to-a-number-the-nesting-number",{"name":175,"value":476},"what-value-will-the-console-output-with-object-property",{"name":178,"value":478},"what-will-be-displayed-in-console-log-arr-0-arr-0",{"name":250,"value":480},"returns-an-array-from-1-to-n-replacing-numbers-that-are-multiples-of-3-with-fizz-numbers-that-are-multiples-of-5-with-buzz-and-numbers-that-are-multiples-of-both-3-and-5-with-fizzbuzz",{"name":280,"value":482},"checks-whether-two-strings-are-anagrams-of-each-other",{"name":286,"value":484},"determines-whether-a-word-is-a-palindrome",{"name":265,"value":486},"there-is-an-array-containing-objects-with-dates-that-need-to-be-sorted-by-date",{"name":292,"value":488},"implement-a-function-that-accepts-arguments-1-b-1c-and-the-return-string-1-b-1c",{"name":256,"value":490},"given-a-tree-nested-object-it-is-necessary-to-find-the-sum-of-all-vertices",{"name":262,"value":492},"for-each-branch-of-the-tree-write-down-the-nesting-number-of-this-branch",{"name":268,"value":494},"there-are-words-in-the-array-it-is-necessary-to-determine-whether-they-consist-of-the-same-letters",{"name":301,"value":496},"the-numbers-from-1-to-100-are-in-the-array-they-are-randomly-mixed-but-it-lacks-one-number-from-this-sequence-it-is-necessary-to-find-him",{"name":271,"value":498},"there-is-a-string-consisting-of-different-brackets-it-is-necessary-to-check-whether-all-are-closed",{"name":277,"value":500},"write-a-function-that-will-make-an-object-out-of-an-array",{"name":181,"value":502},"what-will-console-log-output-as-a-result-of-executing-the-while-loop",{"name":184,"value":504},"there-is-a-function-and-an-object-write-all-the-ways-you-know-to-output-the-value-of-x-from-an-object-in-the-console-using-the-function",{"name":196,"value":506},"what-will-the-console-display-if-a-property-is-assigned-to-an-array-using-a-negative-string-index",{"name":199,"value":508},"what-will-the-console-output-if-an-array-element-is-deleted-using-the-delete-operator",{"name":298,"value":510},"unifying-values-in-an-array",{"name":289,"value":512},"flattening-the-array",{"name":187,"value":514},"what-will-the-book-get-upper-name-method-return",{"name":295,"value":516},"string-compression",{"name":193,"value":518},"what-will-the-console-display-if-a-property-is-assigned-to-an-array-using-a-positive-string-index",{"name":205,"value":520},"what-will-happen-when-an-object-is-passed-as-an-argument-to-a-function-and-the-code-is-executed",{"name":346,"value":522},"how-does-the-browser-know-where-to-get-the-website-after-entering-the-domain",{"name":352,"value":524},"how-does-a-domain-get-into-the-dns-mapping-table-domain-ip",{"name":355,"value":526},"how-does-a-browser-decide-whether-to-open-a-tcp-or-udp-connection",{"name":358,"value":528},"key-differences-between-tcp-and-udp",{"name":361,"value":530},"tcp-ip-who-is-tcp-and-who-is-ip-in-this-case",{"name":364,"value":532},"what-is-http-and-what-does-it-consist-of",{"name":367,"value":534},"what-are-http-headers-and-why-do-we-need-them",{"name":370,"value":536},"what-are-http-parameters",{"name":373,"value":538},"where-is-the-html-code-located-in-the-http-response-structure",{"name":160,"value":540},"what-is-html",{"name":376,"value":542},"what-are-the-differences-between-http-versions-1-0-1-1-2-0-and-3-0",{"name":379,"value":544},"the-user-is-logged-in-on-the-website-how-does-the-server-know-that-i-am-an-authorized-user-when-the-user-logs-in-again",{"name":382,"value":546},"what-is-a-cookie",{"name":385,"value":548},"who-initiates-the-cookie-recording-in-the-browser",{"name":388,"value":550},"is-it-possible-to-manage-cookies-from-the-client-browser",{"name":552,"value":553},"Лайвкодинг","livecoding",{"name":172,"value":555},"what-will-the-following-code-return-object-create-null-has-own-property-to-string",{"name":394,"value":557},"is-everything-that-goes-through-https-secure",{"name":397,"value":559},"all-data-is-encrypted-https-is-used-let-s-assume-a-hacker-hacks-the-dns-and-makes-a-substitution-of-one-ip-for-another-a-phishing-site",{"name":400,"value":561},"there-is-a-web-application-in-addition-to-http-what-other-protocols-of-the-same-level-application-layer-can-be-used-in-the-web-application-in-browser",{"name":411,"value":563},"how-the-browser-parses-javascript-and-images-when-rendering",{"name":408,"value":565},"what-happens-when-http-sends-html-what-does-the-browser-do-with-this-html-given-that-it-is-valid",{"name":414,"value":567},"what-is-blocking-the-page-rendering-in-the-browser",{"name":417,"value":569},"what-is-dom-in-a-browser-what-is-cssom",{"name":420,"value":571},"what-are-nodes-in-the-dom",{"name":423,"value":573},"what-does-cssom-consist-of",{"name":121,"value":575},"the-html-code-is-given-what-will-be-the-color-of-the-some-dummy-text",{"name":124,"value":577},"there-is-a-template-for-html-and-css-code-what-color-will-the-text-thus-constant-have",{"name":127,"value":579},"there-is-a-template-for-embedded-html-code-what-will-be-the-color-of-the-one-more-dummy-text",{"name":130,"value":581},"there-is-a-template-for-embedded-html-code-will-there-be-a-display-does-bodys-block-affect-span",{"name":133,"value":583},"there-is-an-html-code-will-font-weight-affect-span",{"name":136,"value":585},"what-are-the-differences-between-flexbox-and-grid",{"name":139,"value":587},"do-flexbox-and-grid-replace-each-other",{"name":142,"value":589},"there-are-css-and-js-animations-what-is-the-difference-between-them-and-which-is-faster-and-more-convenient",{"name":105,"value":591},"tasks",{"name":208,"value":593},"what-are-the-ways-to-declare-a-function-in-javascript",{"name":211,"value":595},"what-is-this-in-javascript",{"name":214,"value":597},"what-is-an-event-loop-and-how-does-it-work",{"name":217,"value":599},"what-happens-if-you-call-typeof-on-an-undeclared-variable",{"name":220,"value":601},"what-does-the-typeof-operator-show-in-javascript",{"name":223,"value":603},"what-types-of-data-exist-in-javascript",{"name":226,"value":605},"what-is-the-best-structure-to-use-for-storing-an-ordered-list-of-strings-in-javascript",{"name":229,"value":607},"what-will-typeof-return-for-an-array",{"name":232,"value":609},"why-does-the-typeof-operator-applied-to-an-array-return-an-object",{"name":235,"value":611},"if-you-need-to-store-a-list-of-unique-strings-which-data-structure-should-i-choose",{"name":238,"value":613},"what-does-typeof-return-for-new-set-in-javascript",{"name":307,"value":615},"what-is-react-used-for-and-what-problems-does-it-solve",{"name":313,"value":617},"if-you-remove-the-vdom-fiber-in-react-and-manually-change-the-dom-isn-t-that-optimal",{"name":316,"value":619},"there-is-a-block-of-code-what-changes-in-the-real-dom-after-clicking-the-button",{"name":319,"value":621},"there-is-a-code-in-which-there-is-a-list-and-a-button-what-will-change-in-the-real-dom-after-clicking-on-the-button",{"name":322,"value":623},"why-do-we-need-redux-mobx-effector-why-do-we-need-a-state-manager-what-problems-does-it-solve",{"name":340,"value":625},"how-can-diagnose-and-fix-unwanted-background-color-changes-when-clicking-on-a-button-if-the-source-code-of-the-site-is-confusing-and-inaccessible-to-direct-reading",{"name":148,"value":627},"developed-it-committed-it-and-launched-it-it-turned-out-that-i-had-pushed-it-to-the-wrong-branch-or-rather-the-commit-was-in-the-wrong-branch-what-actions",{"name":151,"value":629},"git-has-several-options-for-merging-branches-which-ones-how-are-they-different",{"name":154,"value":631},"what-are-the-branching-strategies-for-the-team-what-is-it",{"name":429,"value":633},"how-does-a-reviewer-know-which-code-is-good-and-which-code-is-bad",{"name":112,"value":635},"here-is-a-fragment-of-a-bash-script-cd-mkdir-foo-what-is-happening-in-this-script",{"name":115,"value":637},"here-is-a-fragment-of-a-bash-script-target-ps-af-grep-1-head-n-1",{"name":331,"value":639},"what-is-algorithmic-complexity",{"name":334,"value":641},"what-is-the-algorithmic-complexity-of-quick-sort",{"name":241,"value":643},"why-do-two-objects-with-the-same-content-return-false-when-compared-in-javascript",{"name":78,"value":645},"how-can-a-user-be-authorized-on-a-website",{"name":244,"value":647},"what-is-the-difference-between-micro-and-macro-tasks-in-javascript",{"name":435,"value":649},"there-are-three-people-in-the-room-what-is-the-probability-that-at-least-two-of-them-are-of-the-same-sex-that-is-two-or-more",{"name":438,"value":651},"there-is-a-coin-it-is-tossed-five-times-in-a-row-each-time-it-is-recorded-whether-it-lands-on-heads-or-tails-how-many-different-sequences-of-heads-and-tails-can-be-obtained",{"name":441,"value":653},"how-can-you-guarantee-to-find-an-easy-fake-coin-among-8-in-the-minimum-number-of-weighings-on-a-balance-scale",{"name":95,"value":96},{"name":391,"value":656},"is-it-true-that-an-attacker-who-controls-a-router-and-listens-to-traffic-can-obtain-logins-and-passwords-from-websites-that-a-client-visits",{"name":349,"value":658},"what-is-dns-and-how-does-dns-find-the-correct-ip-address",{"name":190,"value":660},"variables-are-declared-as-follows-specify-the-correct-statement",{"name":310,"value":662},"what-is-the-underlying-mechanism-for-optimizing-dom-updates-in-react",{"name":325,"value":664},"what-prevents-you-from-organizing-a-centralized-state-without-a-state-manager-if-you-organize-the-state-using-react-context-and-state-mechanisms-what-is-the-problem-what-do-state-managers-add",{"cooperation":666,"copyright":669,"reportError":670,"socialNetwork":672},{"link":667,"title":668},"https://t.me/baurinanton","Сотрудничество","© “GOOD WEB JOB!”",{"label":671,"link":667},"Сообщить об ошибке",{"label":673,"socialNetworkList":674},"Мы в соцсетях:",[675,678,681],{"icon":19,"link":676,"title":677},"https://max.ru/u/f9LHodD0cOKMaukdnnahTeL5pwvjrPfUaZ4S8_1rsNy9I9qsmc9Ar3kP_y8","Max",{"icon":679,"link":667,"title":680},"ic:baseline-telegram","Telegram",{"icon":682,"link":683,"title":684},"ri:vk-fill","https://vk.com/baurinanton","VK",{"data":686,"body":687},{},{"type":688,"children":689},"root",[690],{"type":691,"tag":692,"props":693,"children":694},"element","p",{},[695],{"type":696,"value":78},"text",{"data":698,"body":699},{},{"type":688,"children":700},[701],{"type":691,"tag":692,"props":702,"children":703},{},[704],{"type":696,"value":705},"Авторизация на сайте протекает только через DNS-записи домена, так как DNS определяет права пользователя",{"data":707,"body":708},{},{"type":688,"children":709},[710],{"type":691,"tag":692,"props":711,"children":712},{},[713,715,722],{"type":696,"value":714},"Авторизация может протекать через сессионные cookie (сервер хранит сессию) или через токены (клиент отправляет ",{"type":691,"tag":716,"props":717,"children":719},"code",{"className":718},[],[720],{"type":696,"value":721},"Authorization: Bearer ...",{"type":696,"value":723},"), а также через федеративные схемы вроде OAuth/OIDC",{"data":725,"body":726},{},{"type":688,"children":727},[728],{"type":691,"tag":692,"props":729,"children":730},{},[731],{"type":696,"value":732},"Авторизация выполняется исключительно с помощью CSS и HTML, потому что стили и разметка подтверждают личность",{"data":734,"body":735},{},{"type":688,"children":736},[737],{"type":691,"tag":692,"props":738,"children":739},{},[740],{"type":696,"value":75},{"data":742,"body":743},{},{"type":688,"children":744},[745],{"type":691,"tag":692,"props":746,"children":747},{},[748,750,756],{"type":696,"value":749},"Правильным является вариант, где описан механизм, который сервер может проверять при каждом запросе: cookie/сессия или токен в ",{"type":691,"tag":716,"props":751,"children":753},{"className":752},[],[754],{"type":696,"value":755},"Authorization",{"type":696,"value":757},", а также федеративные протоколы (OAuth). DNS, CSS/HTML и CDN-кэш не предоставляют серверу проверяемого доказательства личности пользователя.",{"data":759,"body":760},{},{"type":688,"children":761},[762,779,784,799,825],{"type":691,"tag":692,"props":763,"children":764},{},[765,771,773,778],{"type":691,"tag":766,"props":767,"children":768},"strong",{},[769],{"type":696,"value":770},"Правильный ответ: 2",{"type":696,"value":772}," - Авторизация может протекать через сессионные cookie (сервер хранит сессию) или через токены (клиент отправляет ",{"type":691,"tag":716,"props":774,"children":776},{"className":775},[],[777],{"type":696,"value":721},{"type":696,"value":723},{"type":691,"tag":692,"props":780,"children":781},{},[782],{"type":696,"value":783},"Разбор вариантов",{"type":691,"tag":785,"props":786,"children":787},"ol",{},[788,794],{"type":691,"tag":789,"props":790,"children":791},"li",{},[792],{"type":696,"value":793},"Неверно: DNS предназначен для работы с доменными именами и ресурсными записями (например, чтобы по имени находить адрес сервера), но не определяет личность пользователя и не задаёт его права на сайте.",{"type":691,"tag":789,"props":795,"children":796},{},[797],{"type":696,"value":798},"Верно: авторизация (в учебных задачах часто имеется в виду «вход и поддержание состояния входа») обычно выполняется:",{"type":691,"tag":800,"props":801,"children":802},"ul",{},[803,808,820],{"type":691,"tag":789,"props":804,"children":805},{},[806],{"type":696,"value":807},"Через сессионные cookie: браузер хранит cookie, сервер хранит сессию.",{"type":691,"tag":789,"props":809,"children":810},{},[811,813,818],{"type":696,"value":812},"Через токены: клиент отправляет токен в заголовке ",{"type":691,"tag":716,"props":814,"children":816},{"className":815},[],[817],{"type":696,"value":721},{"type":696,"value":819},".",{"type":691,"tag":789,"props":821,"children":822},{},[823],{"type":696,"value":824},"Через федеративные схемы: OAuth 2.0 (часто вместе с OpenID Connect для «входа через провайдера»).",{"type":691,"tag":785,"props":826,"children":828},{"start":827},3,[829,834],{"type":691,"tag":789,"props":830,"children":831},{},[832],{"type":696,"value":833},"Неверно: CSS и HTML отвечают за представление и структуру страницы, но не являются механизмами подтверждения личности.",{"type":691,"tag":789,"props":835,"children":836},{},[837],{"type":696,"value":838},"Неверно: кэширование на CDN ускоряет выдачу контента, но не подтверждает личность и не должно «делать пользователя вошедшим». Более того, ошибки кэширования приватных страниц могут приводить к утечкам данных.",{"data":840,"body":841},{},{"type":688,"children":842},[843,848,853,899,904,916,921],{"type":691,"tag":692,"props":844,"children":845},{},[846],{"type":696,"value":847},"Cookie — это небольшой фрагмент данных, который сервер отправляет браузеру, а браузер затем автоматически отправляет обратно этому же сайту в последующих запросах.",{"type":691,"tag":692,"props":849,"children":850},{},[851],{"type":696,"value":852},"Типичный сценарий:",{"type":691,"tag":785,"props":854,"children":855},{},[856,868,873,886],{"type":691,"tag":789,"props":857,"children":858},{},[859,861,867],{"type":696,"value":860},"Пользователь отправляет логин/пароль на ",{"type":691,"tag":716,"props":862,"children":864},{"className":863},[],[865],{"type":696,"value":866},"/login",{"type":696,"value":819},{"type":691,"tag":789,"props":869,"children":870},{},[871],{"type":696,"value":872},"Сервер проверяет данные и создаёт запись сессии на своей стороне (например, в памяти, Redis, базе данных).",{"type":691,"tag":789,"props":874,"children":875},{},[876,878,884],{"type":696,"value":877},"Сервер отправляет cookie с идентификатором сессии (например, ",{"type":691,"tag":716,"props":879,"children":881},{"className":880},[],[882],{"type":696,"value":883},"sid=...",{"type":696,"value":885},").",{"type":691,"tag":789,"props":887,"children":888},{},[889,891,897],{"type":696,"value":890},"Браузер автоматически прикрепляет cookie к следующим запросам, а сервер по ",{"type":691,"tag":716,"props":892,"children":894},{"className":893},[],[895],{"type":696,"value":896},"sid",{"type":696,"value":898}," находит сессию и понимает, кто выполняет запрос.",{"type":691,"tag":692,"props":900,"children":901},{},[902],{"type":696,"value":903},"Пример (упрощённо): создание сессии и установка cookie",{"type":691,"tag":905,"props":906,"children":910},"pre",{"className":907,"code":909,"language":696},[908],"language-text","// Псевдокод: идея одинакова во многих языках/фреймворках\n\nPOST /login\n-> проверить пароль\n-> sessionId = random()\n-> sessions[sessionId] = { userId: 123, createdAt: now(), expiresAt: now()+... }\n-> ответ:\n   Set-Cookie: sid=sessionId; HttpOnly; Secure; SameSite=Lax\n   200 OK\n\nGET /profile\n(браузер автоматически отправляет Cookie: sid=sessionId)\n-> сервер читает sid\n-> находит sessions[sid]\n-> если найдено и не истекло, отдаёт страницу/JSON\n",[911],{"type":691,"tag":716,"props":912,"children":914},{"__ignoreMap":913},"",[915],{"type":696,"value":909},{"type":691,"tag":692,"props":917,"children":918},{},[919],{"type":696,"value":920},"Зачем серверное хранилище сессий удобно:",{"type":691,"tag":800,"props":922,"children":923},{},[924,929,934],{"type":691,"tag":789,"props":925,"children":926},{},[927],{"type":696,"value":928},"Можно быстро «отозвать» вход: достаточно удалить сессию на сервере.",{"type":691,"tag":789,"props":930,"children":931},{},[932],{"type":696,"value":933},"Можно хранить дополнительные признаки (например, время входа, устройство, CSRF-токен, флаги безопасности).",{"type":691,"tag":789,"props":935,"children":936},{},[937],{"type":696,"value":938},"Можно централизованно применять правила (ограничение по времени, принудительный выход).",{"data":940,"body":941},{},{"type":688,"children":942},[943,948,953,958],{"type":691,"tag":692,"props":944,"children":945},{},[946],{"type":696,"value":947},"В веб-разработке важно различать два близких понятия. Аутентификация отвечает на вопрос «кто это?», а авторизация — «что этому разрешено делать?».",{"type":691,"tag":692,"props":949,"children":950},{},[951],{"type":696,"value":952},"В учебных вопросах словом «авторизация» часто называют именно процесс входа, то есть проверку личности, и последующее поддержание состояния «пользователь вошёл». Поскольку HTTP-запросы сами по себе не содержат «памяти о прошлом», серверу требуется получать при каждом запросе некоторый идентификатор или доказательство того, что запрос выполняется от имени конкретного пользователя.",{"type":691,"tag":692,"props":954,"children":955},{},[956],{"type":696,"value":957},"Отсюда возникает практическая задача: после успешного входа необходимо «привязать» дальнейшие запросы к пользователю, чтобы сервер мог:",{"type":691,"tag":800,"props":959,"children":960},{},[961,966,971],{"type":691,"tag":789,"props":962,"children":963},{},[964],{"type":696,"value":965},"Узнать пользователя.",{"type":691,"tag":789,"props":967,"children":968},{},[969],{"type":696,"value":970},"Проверить срок действия входа.",{"type":691,"tag":789,"props":972,"children":973},{},[974],{"type":696,"value":975},"Проверить права (роль, доступ к конкретным ресурсам).",{"data":977,"body":978},{},{"type":688,"children":979},[980],{"type":691,"tag":692,"props":981,"children":982},{},[983],{"type":696,"value":18},{"data":985,"body":986},{},{"type":688,"children":987},[988],{"type":691,"tag":692,"props":989,"children":990},{},[991,993,999,1001,1007,1008,1014],{"type":696,"value":992},"Если злоумышленник получит значение cookie с идентификатором сессии, может возникнуть захват сессии. Поэтому важны HTTPS и корректные атрибуты cookie (например, ",{"type":691,"tag":716,"props":994,"children":996},{"className":995},[],[997],{"type":696,"value":998},"HttpOnly",{"type":696,"value":1000},", ",{"type":691,"tag":716,"props":1002,"children":1004},{"className":1003},[],[1005],{"type":696,"value":1006},"Secure",{"type":696,"value":1000},{"type":691,"tag":716,"props":1009,"children":1011},{"className":1010},[],[1012],{"type":696,"value":1013},"SameSite",{"type":696,"value":1015},") и защита от XSS.",{"data":1017,"body":1018},{},{"type":688,"children":1019},[1020,1031,1043,1048,1057,1062,1071],{"type":691,"tag":692,"props":1021,"children":1022},{},[1023,1025,1030],{"type":696,"value":1024},"Токенный подход означает, что клиент хранит токен и отправляет его с каждым запросом к защищённому API. Часто токен передаётся в заголовке авторизации: ",{"type":691,"tag":716,"props":1026,"children":1028},{"className":1027},[],[1029],{"type":696,"value":721},{"type":696,"value":819},{"type":691,"tag":692,"props":1032,"children":1033},{},[1034,1036,1042],{"type":696,"value":1035},"Это описано в спецификациях семейства OAuth 2.0 (например, RFC 6750 для Bearer Token Usage), где задаётся стандартный формат передачи токена, включая пример заголовка ",{"type":691,"tag":716,"props":1037,"children":1039},{"className":1038},[],[1040],{"type":696,"value":1041},"Authorization: Bearer \u003Ctoken>",{"type":696,"value":819},{"type":691,"tag":692,"props":1044,"children":1045},{},[1046],{"type":696,"value":1047},"Пример HTTP-запроса с Bearer-токеном",{"type":691,"tag":905,"props":1049,"children":1052},{"className":1050,"code":1051,"language":696},[908],"GET /api/orders HTTP/1.1\nHost: example.com\nAuthorization: Bearer eyJhbGciOi...\n",[1053],{"type":691,"tag":716,"props":1054,"children":1055},{"__ignoreMap":913},[1056],{"type":696,"value":1051},{"type":691,"tag":692,"props":1058,"children":1059},{},[1060],{"type":696,"value":1061},"Пример серверной проверки (упрощённо)",{"type":691,"tag":905,"props":1063,"children":1066},{"className":1064,"code":1065,"language":696},[908],"function authMiddleware(req):\n  header = req.headers[\"authorization\"]\n\n  if header is missing:\n    return 401\n\n  if not header startsWith \"Bearer \":\n    return 401\n\n  token = header after \"Bearer \"\n  claims = verifyAndDecode(token) // подпись, срок действия, аудитория и т.п.\n\n  if claims invalid:\n    return 401\n\n  req.userId = claims.sub\n  return next()\n",[1067],{"type":691,"tag":716,"props":1068,"children":1069},{"__ignoreMap":913},[1070],{"type":696,"value":1065},{"type":691,"tag":692,"props":1072,"children":1073},{},[1074],{"type":696,"value":1075},"Особенность Bearer-токена: «кто владеет токеном, тот и проходит проверку». Поэтому утечка токена обычно равна утечке доступа на время жизни токена, и требуется строго защищать каналы передачи (TLS) и место хранения.",{"data":1077,"body":1078},{},{"type":688,"children":1079},[1080],{"type":691,"tag":692,"props":1081,"children":1082},{},[1083],{"type":696,"value":39},{"data":1085,"body":1086},{},{"type":688,"children":1087},[1088,1093,1098,1154,1159],{"type":691,"tag":692,"props":1089,"children":1090},{},[1091],{"type":696,"value":1092},"OAuth 2.0 — это стандарт, описывающий делегирование доступа: клиентское приложение получает токен доступа к ресурсам от сервера авторизации. В сценарии «вход через провайдера» (например, через отдельный аккаунт-провайдер) OAuth 2.0 часто используется совместно со стандартами, которые добавляют «слой идентичности» (например, OpenID Connect).",{"type":691,"tag":692,"props":1094,"children":1095},{},[1096],{"type":696,"value":1097},"Один из распространённых потоков — Authorization Code:",{"type":691,"tag":785,"props":1099,"children":1100},{},[1101,1106,1111,1122,1149],{"type":691,"tag":789,"props":1102,"children":1103},{},[1104],{"type":696,"value":1105},"Клиент перенаправляет браузер пользователя на endpoint авторизации.",{"type":691,"tag":789,"props":1107,"children":1108},{},[1109],{"type":696,"value":1110},"Пользователь аутентифицируется на стороне сервера авторизации и подтверждает согласие.",{"type":691,"tag":789,"props":1112,"children":1113},{},[1114,1116,1121],{"type":696,"value":1115},"Сервер авторизации перенаправляет браузер обратно на сайт клиента с параметром ",{"type":691,"tag":716,"props":1117,"children":1119},{"className":1118},[],[1120],{"type":696,"value":716},{"type":696,"value":819},{"type":691,"tag":789,"props":1123,"children":1124},{},[1125,1127,1132,1134,1140,1142,1148],{"type":696,"value":1126},"Сервер клиента (или доверенный backend) обменивает ",{"type":691,"tag":716,"props":1128,"children":1130},{"className":1129},[],[1131],{"type":696,"value":716},{"type":696,"value":1133}," на ",{"type":691,"tag":716,"props":1135,"children":1137},{"className":1136},[],[1138],{"type":696,"value":1139},"access_token",{"type":696,"value":1141}," (и иногда ",{"type":691,"tag":716,"props":1143,"children":1145},{"className":1144},[],[1146],{"type":696,"value":1147},"refresh_token",{"type":696,"value":885},{"type":691,"tag":789,"props":1150,"children":1151},{},[1152],{"type":696,"value":1153},"Далее запросы к API выполняются с предъявлением токена.",{"type":691,"tag":692,"props":1155,"children":1156},{},[1157],{"type":696,"value":1158},"Схема (упрощённо) Authorization Code Flow",{"type":691,"tag":905,"props":1160,"children":1163},{"className":1161,"code":1162,"language":696},[908],"Пользователь -> Клиент (сайт) -> Сервер авторизации -> Клиент -> Ресурсный сервер\n\n1) Клиент: redirect на /authorize\n2) Сервер авторизации: вход + согласие\n3) Redirect обратно: ?code=...\n4) Клиент: POST /token (обмен code на access_token)\n5) Клиент/приложение: запросы к API с access_token\n",[1164],{"type":691,"tag":716,"props":1165,"children":1166},{"__ignoreMap":913},[1167],{"type":696,"value":1162},{"data":1169,"body":1170},{},{"type":688,"children":1171},[1172],{"type":691,"tag":692,"props":1173,"children":1174},{},[1175],{"type":696,"value":1176},"Смысл федеративной схемы в том, что пароль пользователя не передаётся стороннему сайту: ввод учётных данных происходит только на стороне сервера авторизации.",{"data":1178,"body":1179},{},{"type":688,"children":1180},[1181,1186,1191,1196,1201],{"type":691,"tag":692,"props":1182,"children":1183},{},[1184],{"type":696,"value":1185},"DNS:\nDNS решает задачу именования (как по доменному имени находить нужные сетевые параметры), но не содержит модели «конкретный пользователь вошёл в систему» и не обеспечивает проверку прав на уровне запросов к веб-приложению.",{"type":691,"tag":692,"props":1187,"children":1188},{},[1189],{"type":696,"value":1190},"CSS/HTML:\nCSS описывает внешний вид (оформление), HTML — структуру документа. Эти технологии не предназначены для криптографической проверки личности и не дают серверу проверяемого доказательства, что запрос сделан именно конкретным пользователем.",{"type":691,"tag":692,"props":1192,"children":1193},{},[1194],{"type":696,"value":1195},"CDN-кэш:\nCDN занимается доставкой и кэшированием. Кэш может хранить и повторно выдавать ответы, но это не является подтверждением личности. Наоборот, при неправильных настройках кэша возможно случайное распространение приватного контента, поэтому приватные страницы обычно помечаются так, чтобы кэширование происходило безопасно (или не происходило вовсе), а доступ контролировался cookie/токенами на сервере.",{"type":691,"tag":692,"props":1197,"children":1198},{},[1199],{"type":696,"value":1200},"Таблица: чем отличаются подходы",{"type":691,"tag":1202,"props":1203,"children":1204},"table",{},[1205,1239],{"type":691,"tag":1206,"props":1207,"children":1208},"thead",{},[1209],{"type":691,"tag":1210,"props":1211,"children":1212},"tr",{},[1213,1219,1224,1229,1234],{"type":691,"tag":1214,"props":1215,"children":1216},"th",{},[1217],{"type":696,"value":1218},"Подход",{"type":691,"tag":1214,"props":1220,"children":1221},{},[1222],{"type":696,"value":1223},"Что отправляется в каждом запросе",{"type":691,"tag":1214,"props":1225,"children":1226},{},[1227],{"type":696,"value":1228},"Где хранится «состояние входа»",{"type":691,"tag":1214,"props":1230,"children":1231},{},[1232],{"type":696,"value":1233},"Типичный плюс",{"type":691,"tag":1214,"props":1235,"children":1236},{},[1237],{"type":696,"value":1238},"Типичный риск/сложность",{"type":691,"tag":1240,"props":1241,"children":1242},"tbody",{},[1243,1285,1316],{"type":691,"tag":1210,"props":1244,"children":1245},{},[1246,1252,1263,1275,1280],{"type":691,"tag":1247,"props":1248,"children":1249},"td",{},[1250],{"type":696,"value":1251},"Сессионные cookie",{"type":691,"tag":1247,"props":1253,"children":1254},{},[1255,1261],{"type":691,"tag":716,"props":1256,"children":1258},{"className":1257},[],[1259],{"type":696,"value":1260},"Cookie: sid=...",{"type":696,"value":1262}," (автоматически браузером)",{"type":691,"tag":1247,"props":1264,"children":1265},{},[1266,1268,1273],{"type":696,"value":1267},"На сервере (сессия по ",{"type":691,"tag":716,"props":1269,"children":1271},{"className":1270},[],[1272],{"type":696,"value":896},{"type":696,"value":1274},")",{"type":691,"tag":1247,"props":1276,"children":1277},{},[1278],{"type":696,"value":1279},"Удобно для классических сайтов, легко отзывать сессию",{"type":691,"tag":1247,"props":1281,"children":1282},{},[1283],{"type":696,"value":1284},"Риски при XSS/угоне cookie, важны атрибуты безопасности",{"type":691,"tag":1210,"props":1286,"children":1287},{},[1288,1293,1301,1306,1311],{"type":691,"tag":1247,"props":1289,"children":1290},{},[1291],{"type":696,"value":1292},"Bearer-токен",{"type":691,"tag":1247,"props":1294,"children":1295},{},[1296],{"type":691,"tag":716,"props":1297,"children":1299},{"className":1298},[],[1300],{"type":696,"value":721},{"type":691,"tag":1247,"props":1302,"children":1303},{},[1304],{"type":696,"value":1305},"Часто «внутри» токена и/или в системе проверки",{"type":691,"tag":1247,"props":1307,"children":1308},{},[1309],{"type":696,"value":1310},"Удобно для API и разных клиентов",{"type":691,"tag":1247,"props":1312,"children":1313},{},[1314],{"type":696,"value":1315},"Утечка токена обычно даёт доступ, важны срок жизни и отзыв",{"type":691,"tag":1210,"props":1317,"children":1318},{},[1319,1324,1329,1334,1339],{"type":691,"tag":1247,"props":1320,"children":1321},{},[1322],{"type":696,"value":1323},"OAuth 2.0",{"type":691,"tag":1247,"props":1325,"children":1326},{},[1327],{"type":696,"value":1328},"После получения — предъявление access token",{"type":691,"tag":1247,"props":1330,"children":1331},{},[1332],{"type":696,"value":1333},"Сервер авторизации выдаёт токены, ресурсный сервер проверяет",{"type":691,"tag":1247,"props":1335,"children":1336},{},[1337],{"type":696,"value":1338},"Делегирование доступа, пароль не передаётся клиенту",{"type":691,"tag":1247,"props":1340,"children":1341},{},[1342],{"type":696,"value":1343},"Больше компонентов и настроек, важны redirect URI и безопасность потока",{"data":1345,"body":1346},{},{"type":688,"children":1347},[1348],{"type":691,"tag":692,"props":1349,"children":1350},{},[1351,1353,1358],{"type":696,"value":1352},"Итого: авторизация (в смысле «вход и поддержание состояния входа») обычно реализуется через сессионные cookie или через токены (например, ",{"type":691,"tag":716,"props":1354,"children":1356},{"className":1355},[],[1357],{"type":696,"value":721},{"type":696,"value":1359},"), а для входа через внешнего провайдера применяется OAuth 2.0; DNS, CSS/HTML и CDN-кэш не предназначены для подтверждения личности пользователя.",1775735658910]