Я начинаю планировать REST API с помощью node.js, express и mongodb. API предоставляет данные для веб-сайта (публичного и частного) и, возможно, мобильного приложения. Интерфейс будет разработан с AngularJS.
В течение нескольких дней я много читал о защите REST API, но не нашел окончательного решения. Насколько я понимаю, это использовать HTTPS для обеспечения базовой безопасности. Но как я могу защитить API в этих случаях использования:
Только посетители / пользователи веб-сайта / приложения могут получать данные для публичной части веб-сайта / приложения.
Только аутентифицированные и авторизованные пользователи могут получать данные для приватной области (и только данные, для которых пользователю предоставлены разрешения).
На данный момент я думаю, что только пользователи с активным сеансом могут использовать API. Для авторизации пользователей я буду использовать паспорт, а для разрешения мне нужно что-то реализовать для себя. Все на вершине HTTPS.
Может ли кто-нибудь предоставить лучшую практику или опыт? Есть ли недостаток в моей «архитектуре»?
источник
Ответы:
У меня была та же проблема, которую вы описали. Веб-сайт, который я создаю, доступен с мобильного телефона и из браузера, поэтому мне нужен API, чтобы пользователи могли зарегистрироваться, войти в систему и выполнить некоторые конкретные задачи. Кроме того, мне нужно поддерживать масштабируемость, один и тот же код, работающий на разных процессах / машинах.
Поскольку пользователи могут СОЗДАТЬ ресурсы (также называемые действиями POST / PUT), вам необходимо защитить свой API. Вы можете использовать oauth или создать собственное решение, но имейте в виду, что все решения могут быть взломаны, если пароль действительно легко найти. Основная идея состоит в том, чтобы аутентифицировать пользователей, используя имя пользователя, пароль и токен, он же apitoken. Этот apitoken может быть сгенерирован с помощью node-uuid, а пароль - с помощью pbkdf2.
Затем вам нужно где-то сохранить сессию. Если вы сохраните его в памяти в виде простого объекта, если вы убьете сервер и перезагрузите его снова, сеанс будет уничтожен. Кроме того, это не масштабируется. Если вы используете haproxy для балансировки нагрузки между компьютерами или просто используете рабочих, это состояние сеанса будет сохранено в одном процессе, поэтому, если тот же пользователь перенаправлен на другой процесс / машину, ему потребуется снова пройти аутентификацию. Поэтому вам нужно хранить сессию в общем месте. Обычно это делается с помощью Redis.
Когда пользователь проходит проверку подлинности (имя пользователя + пароль + apitoken), генерируется еще один токен для сеанса, он же accesstoken. Опять же, с node-uuid. Отправьте пользователю маркер доступа и ИД пользователя. Идентификатор пользователя (ключ) и токен доступа (значение) сохраняются в redis со временем истечения срока действия, например, 1 час.
Теперь каждый раз, когда пользователь выполняет какую-либо операцию, используя остальные API, ему нужно будет отправить идентификатор пользователя и маркер доступа.
Если вы разрешите пользователям регистрироваться, используя остальные API, вам нужно будет создать учетную запись администратора с помощью apitoken администратора и сохранить их в мобильном приложении (зашифровать имя пользователя + пароль + apitoken), поскольку у новых пользователей не будет apitoken, когда они подписываются.
Интернет также использует этот API, но вам не нужно использовать apitokens. Вы можете использовать Express с Redis Store или использовать тот же метод, описанный выше, но обходя проверку apitoken и возвращая пользователю идентификатор пользователя + accesstoken в cookie.
Если у вас есть личные области, сравните имя пользователя с разрешенными пользователями при аутентификации. Вы также можете применять роли к пользователям.
Резюме:
Альтернативой без использования apitoken было бы использование HTTPS и отправка имени пользователя и пароля в заголовке авторизации и кэширование имени пользователя в redis.
источник
apitoken
? это "вторичный" пароль?Я хотел бы внести этот код в качестве структурного решения поставленного вопроса в соответствии с (я надеюсь, что так) принятым ответом. (Вы можете очень легко настроить его).
Этот сервер можно протестировать с помощью curl:
источник
Я только что закончил пример приложения, которое делает это довольно простым, но понятным способом. Он использует mongoose с mongodb для хранения пользователей и паспорт для управления аутентификацией.
https://github.com/Khelldar/Angular-Express-Train-Seed
источник
Есть много вопросов о шаблонах аутентификации REST здесь на SO. Вот наиболее актуальные для вашего вопроса:
В основном вам нужно выбирать между использованием ключей API (наименее безопасным, так как ключ может быть обнаружен неавторизованным пользователем), ключом приложения и комбинацией токенов (средний) или полной реализацией OAuth (наиболее безопасный).
источник
Если вы хотите защитить свое приложение, то вам определенно следует начать с использования HTTPS вместо HTTP , это обеспечит создание безопасного канала между вами и пользователями, что предотвратит перехват данных, отправляемых пользователям назад и вперед, и поможет сохранить данные обменялись конфиденциально.
Вы можете использовать JWT (JSON Web Tokens) для защиты API RESTful , это имеет много преимуществ по сравнению с сеансами на стороне сервера, преимущества в основном:
1 - Более масштабируемый, так как ваши серверы API не должны будут поддерживать сеансы для каждого пользователя (что может быть большим бременем, когда у вас много сеансов)
2. JWT являются самодостаточными и имеют утверждения, которые определяют роль пользователя, например, и к чему он может получить доступ, а также выдан на дату и дату истечения срока действия (после чего JWT не будет действительным)
3. Легче обрабатывать балансировщики нагрузки, и если у вас есть несколько серверов API, поскольку вам не нужно обмениваться данными сеанса и не настраивать сервер для маршрутизации сеанса на один и тот же сервер, когда запрос с JWT попадает на любой сервер, он может быть аутентифицирован & авторизовано
4- Меньшая нагрузка на вашу базу данных, а также вам не придется постоянно хранить и извлекать идентификатор сессии и данные для каждого запроса
5- JWT не могут быть подделаны, если вы используете сильный ключ для подписи JWT, поэтому вы можете доверять утверждениям в JWT, отправляемом с запросом, без необходимости проверять сеанс пользователя и проверять, авторизован он или нет , вы можете просто проверить JWT, и тогда вы все будете знать, кто и что может сделать этот пользователь.
Многие библиотеки предоставляют простые способы создания и проверки JWT на большинстве языков программирования, например: в node.js одним из самых популярных является jsonwebtoken
Так как API REST обычно стремятся сохранить сервер без сохранения состояния, JWT более совместимы с этой концепцией, поскольку каждый запрос отправляется с помощью автономного токена авторизации (JWT), при этом серверу не нужно отслеживать сеанс пользователя по сравнению с сеансами, которые делают Сервер с состоянием, так что он запоминает пользователя и его роль, однако сессии также широко используются и имеют свои плюсы, которые вы можете искать, если хотите.
Важно отметить, что вы должны безопасно доставить JWT клиенту, используя HTTPS, и сохранить его в безопасном месте (например, в локальном хранилище).
Вы можете узнать больше о JWT по этой ссылке
источник
Если вы хотите иметь полностью заблокированную область вашего веб-приложения, доступ к которой могут получить только администраторы вашей компании, тогда SSL-авторизация может быть для вас. Это гарантирует, что никто не сможет подключиться к экземпляру сервера, если в его браузере не установлен авторизованный сертификат. На прошлой неделе я написал статью о том, как настроить сервер: Статья
Это одна из самых безопасных настроек, которую вы найдете, так как здесь не используются имена пользователей и пароли, поэтому никто не сможет получить доступ, пока один из ваших пользователей не передаст файлы ключей потенциальному хакеру.
источник