Заметки в категории «Разное»

Код состояния HTTP для неавторизованного пользователя

Среди официального списка кодов состояний HTTP есть такой код:

401 Unauthorized

The request requires user authentication.

И разработчики ошибочно начинают его применять в ответах на REST-запросы асинхронные запросы, чтобы сообщить браузеру о том, что текущий пользователь их приложения не авторизован. Это в корне неверно.

В описании кода 401 ясно указано, что вместе с таким ответом сервер должен передать заголовок WWW-Authenticate с перечнем условий. А браузер может повторить запрос, включив в него заголовок Authorization с требуемыми для аутентификации данными.

Чаще всего в реальной жизни этот код можно встретить, если доступ к ресурсу защищён паролем. Например, в Apache это можно сделать добавив в конфигурацию следующие строки:

AuthName "Secure Area"
AuthType Basic
AuthUserFile "/usr/local/apache/passwd/passwords"
Require valid-user

Браузер попросит пользователя ввести логин и пароль и будет в дальнейшем их использовать для доступа ко всем ресурсам, защищенным такой базовой аутентификацией. Замечу, что введённые данные будут каждый раз передаваться в открытом виде в заголовках запросов.

Очевидно, что такая проверка уровня доступа пользователя к запрашиваемому ресурсу по протоколу HTTP никак не связана с разграничением прав пользователей внутри сервера приложения.

А как лучше?

По моему мнению, разумнее отвечать неавторизованному пользователю кодом 403 Forbiden

403 Forbidden

The server understood the request, but is refusing to fulfill it.

А в теле ответа передать JSON с описанием проблемы.

Комментарии к заметке: 4

Знакомство с AWS Lambda

Amazon Web Services Lambda — это веб-сервис, запускающий ваш код на Node.js, Python или Java в ответ на определенные события и отвечающий за автоматическое выделение необходимых вычислительных ресурсов. Функции Lambda не хранят состояние, поэтому AWS Lambda может быстро запустить столько копий функции, сколько нужно для обработки входящих событий.

Оплата производится за количество вызовов функции и время, необходимое для исполнения кода этой функции. Изучение и маленькие домашние проекты для вас могут быть совершенно бесплатными в течение года с момента регистрации в AWS.

Создание пользователя

После регистрации в AWS нужно создать пользователя и назначить ему права доступа к сервисам.

Все инструкции вы найдёте в документации AWS Identity and Access Management «IAM Users». Сохраните файл с ключами — они потребуются при настройке CLI.

Только что созданный пользователь не имеет никаких прав. Чтобы он получил доступ к созданию и запуску функций Lambda, нужно назначить ему соответствующую политику. В разделе «Working with Policies» описано как добраться до списка политик. Нам нужно добавить для пользователя политику «AWSLambdaFullAccess». Позже аналогично можно будет добавить или удалить другие политики.

AWS Command Line Interface

Почти все функции AWS доступны через веб-интерфейс, но на практике удобнее использовать консольные команды или скрипты.

Инструкции по установке утилит вы найдёте на странице «AWS Command Line Interface». После того как вы проделаете все описанные там действия, запустите команду:

aws configure

и укажите ключи пользователя, которые вы получили при его создании. Я так же выбрал регион по-умолчанию «eu-central-1». В разных регионах доступны разные наборы сервисов.

Создание функции AWS Lambda

Для начала, напишем простой скрипт, который будет возвращать строку "Hello, world!". Так же в логах мы увидим с какими параметрами вызывалась функция.

'use strict';

exports.handler = (event, context, callback) => {
  console.log(JSON.stringify(event, null, 2));
  callback(null, 'Hello, world!');
};

Сохраним этот код в файл index.js.

В принципе, функция может быть любой сложности и использовать другие модули из npm. Все файлы потом будут запакованы в один архив.

Перед тем как загрузить функцию в AWS, нужно создать роль для неё. Если у вас уже существует подходящая роль, то этот шаг можно пропустить.

aws iam create-role \
  --role-name MyFirstLambda-Execution \
  --assume-role-policy-document '{
    "Version": "2012-10-17",
    "Statement": [{
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }]
  }' \
  --output text \
  --query 'Role.Arn'

В ответ вы получите строку вида:

arn:aws:iam::000000000000:role/MyFirstLambda-Execution

Так как наша функция будет вести логгирование, то нужно добавить ей соответствующую политику. Иначе лог не сохранится в CloudWatch.

aws iam attach-role-policy \
  --role-name MyFirstLambda-Execution \
  --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

Вот теперь можно загрузить нашу функцию в Lambda.

zip - index.js | \
aws lambda create-function \
  --function-name MyFirstLambda \
  --runtime nodejs4.3 \
  --role arn:aws:iam::000000000000:role/MyFirstLambda-Execution \
  --handler index.handler \
  --zip-file fileb:///dev/stdin

Код функции будет архивироваться и загружаться в AWS без создания временных файлов. Так же код можно загружать через S3.

В параметре --handler указываем точку входа — название модуля (index) и метод, который экспортирует модуль.

В параметре --role указываем роль, которую мы создали для запуска функции.

Выполнение функции

Запустить функцию можно из терминала

aws lambda invoke \
  --function-name MyFirstLambda \
  /tmp/out.json && cat /tmp/out.json

Результат сохранится в файл /tmp/out.json, содержимое которого мы затем выведем в терминале.

aws lambda invoke \
  --function-name MyFirstLambda \
  --payload '{"foo":1,"bar":true}' \
  /tmp/out.json

Обновление кода и конфигурации функции

Обновляется код функции аналогично тому как она создавалась.

zip - index.js | \
aws lambda update-function-code \
  --function-name MyFirstLambda \
  --zip-file fileb:///dev/stdin

Если нужно обновить какие-то параметры конфигурации, то это делается командой update-function-configuration.

Заключение

С AWS Lambda можно легко получить масштабируемое окружение.

На практике функции вызываются по какому-либо событию. Например, запуск по расписанию, обновление таблицы в DynamoDB, появление файла в S3 или при поступлении HTTP-запроса в сервис API Gateway.

В свою очередь, код Lambda-функции может взаимодействовать с другими серверами AWS, внешними базами данных и веб-ресурсами.

Оставте свой комментарий

Конференции, на которых я был в 2015 году

Для меня сезон выступлений на конференциях начался только в мае.

В Москве в рамках фестиваля РИТ в этом году проходила большая конференция FrontendConf. Для неё я подготовил доклад «Пакуйте чемоданы. Грузите апельсины» (слайды). Модульная структура JS-приложения и инструменты для сборки уже стали признаком хорошего тона. Я сделал обзорный доклад, в котором рассказал о текущем состоянии технологий и инструментов для работы с JS-модулями.

В целом, у меня остались только приятные впечатления от организации самой конференции. Доклады были организованы в два параллельных потока. А по окончании первого дня, были устроены дискуссии, где докладчики и слушатели могли высказать своё мнение на заданную тему.

Практически в то же время, когда я подавал заявку на FrontendConf, меня пригласили выступить на UWDC с докладом «От простого к сложному» (слайды). В этом году уклон всей секции был сделал на разработку под мобильные устройства.

Пикантность ситуации заключалась в том, что в четверг и пятницу я был в Москве на FrontendConf, а в субботу уже должен был быть в Челябинске на UWDC. В тщательно продуманный план закралась неопределённость в виде московского метро. Я опоздал на нужный мне рейс аэроэкспресса. Следующий прибывал в аэропорт уже впритык ко времени посадки. Я зарегистрировался через приложение, но у меня не было распечатанного посадочного талона.

Несмотря ни на что, я успел на свой рейс! Эта ситуация меня ещё раз научила тому, что не стоит опускать руки, если ты в силах ещё что-то изменить.

Летом я выступал на митапах ChellyJS в Челябинске и 4front в Минске с докладом «Переходи на HTTPS!». В своё время меня очень заинтересовала эта тема. Казалось, что настройка безопасного соединения подвластна только бородатым сисадминам. Однако, на практике это совсем не так.

Встреча 4front для меня стала особенной из-за того, что я первый раз приехал в Минск. А ещё этот день совпал с днём моего рождения. Огромное спасибо ребятам, с которыми мы душевно посидели в кафешке после докладов.

В сентябре в Екатеринбурге уже традиционно проходит большая конференция FrontTalks. Мне очень нравится формат и подготовка этого мероприятия. Я всегда с удовольствием приезжаю на неё с каким-нибудь докладом. В этом году одним из трендов в веб-разработке стал webpack. В отличии от обзорного доклада, который я делал на FrontendConf, тут я решил рассказать о том, как именно webpack позволяет упростить некоторые рутинные задачи. Мой доклад «Глубокое погружение в webpack» доступен в записи или слайдах. Ведущие так тепло представили меня, что я даже растрогался и немного позабыл о чём хотел рассказать.

Кроме этого, весной я был на DUMP. Организаторы FrontTalks делают там секцию, просвещённую фронтенд разработке. Как и любая многопоточная конференция, она хороша тем, что всегда можно найти тему, которую было бы интересно послушать. С другой стороны, очень часто такие интересные доклады пересекаются.

А в октябре я уже четвёртый год подряд езжу на Fronteers в Амстердам. В этот раз я вёл текстовую трансляцию мероприятия для сообщества «Веб-стандарты». Логи доступны на Гитхабе — первый день, второй день. (Примечание: кликайте по ссылкам на pic.twitter.com — там очень часто я прикреплял несколько картинок, но выгрузились только первые из них).

И ещё, десятки часов я провёл за просмотром онлайн-трансляций других мероприятий. Могу с уверенностью сказать, что это время не было потрачено в пустую. Не стойте на месте, развивайтесь и совершенствуйтесь!

Комментарии к заметке: 2

RAM-диск в OS X

RAM-диск — это логический том, расположенный в оперативной памяти компьютера. Его польза очевидна: скорость доступа к информации в оперативной памяти несравненно выше, чем скорость доступа к жесткому диску или диску на твёрдотельном накопителе (SSD). Но есть и негативный момент: данные в оперативной памяти безвозвратно стираются при перезагрузке компьютера или отключении питания.

Тем не менее, существуют ситуации, когда скорость может иметь решающее значение. Это может быть, например, пакетная обработка изображений. Мне приходилось оптимизировать около 1 Гигабайта PNG-изображений, ещё попутно конвертируя их в WebP формат. Потом нужно было создать архив для загрузки финальных картинок на сервер. С RAM-диском все эти операции производились гораздо быстрее. Потеря данных на любом этапе не была критической — нужно было всего-лишь перезапустить скрипт.

Итак, чтобы создать RAM-диск, в терминале выполним команду:

diskutil erasevolume HFS+ 'RAM Disk' `hdiutil attach -nomount ram://XXXXX`

Замените символы XXXXX на количество блоков. Это количество вычисляется по формуле размер_в_байтах / 512. Для дисков в несколько Гигабайт можно пользоваться грубой формулой размер_в_Гбайт * 2000000.

Создать RAM-диск в терминале

Реальная память под диск будет выделяться по мере его заполнения данными и полностью освобождается только когда диск будет размонтирован.

Комментарии к заметке: 1