Я создал сценарий входа, который аутентифицирует фронтенд-приложение (написанное на Vue.js) для получения user_api_key пользователя Discourse, следуя рекомендациям, изложенным @samздесь.
Аутентификация работает, однако меня беспокоит безопасное хранение закрытого ключа. В данный момент закрытый ключ хранится локально в файле .env и используется для шифрования/дешифрования полезной нагрузки. Является ли это безопасным способом шифрования полезной нагрузки, и если нет — какие существуют альтернативы для фронтенд-приложения на JavaScript?
Как в приложении Electron/Tauri? Я не знаю, что вы выберете. Предполагаю, что у них есть какой-то механизм для безопасного хранения. Возможно, если вам повезёт, вы сможете использовать связку ключей на Mac и что-то подобное на Windows.
Это веб-приложение, размещённое на сервере. Проблема заключается в том, что полезная нагрузка может быть перехвачена, если закрытый ключ будет скомпрометирован. Я понимаю, что это более общая проблема шифрования в JavaScript, но спрашиваю на случай, если существует более безопасная практика аутентификации веб-приложения от Discourse.
Система пользовательских API-ключей не предназначена для этого сценария. Если вы уже проделываете всю работу по генерации приватного ключа и затем храните его на сервере от имени пользователя, зачем усложнять себе жизнь? Просто генерируйте ключи на стороне сервера.
Мне крайне сложно дать какие-либо рекомендации, не понимая до конца, в чём именно заключается проблема. Почему бы просто не реализовать прокси-эндпоинты в вашем веб-приложении и не обрабатывать всю аутентификацию внутри него?
После обсуждения с моим коллегой @owengot вот более подробное описание проблемы.
Существует веб-приложение на базе Vue.js, у которого нет собственного активного серверного компонента. Это автономное веб-приложение, использующее API Discourse, то есть в некотором роде сервером выступает сам Discourse. Примеры использования: автономные опросы или формы, где контент публикуется в темы Discourse от имени пользователя. Возможность создавать такое программное обеспечение без кастомных серверных компонентов казалась привлекательной архитектурой для таких задач, поэтому в идеале мы хотели бы избежать любой работы «на стороне сервера».
Теперь о том, как получить ключ User-API: это работает как задумано, но @owengot обнаружил, что этап генерации закрытого ключа в JavaScript занимает много времени (до 10 секунд, это просто неэффективно в JavaScript…). Затем он нашёл обходной путь: один и тот же закрытый ключ можно использовать для нескольких пользователей, поэтому он сохранил его в файл на веб-хостинге, который также обслуживает другие статические файлы веб-приложения (JS, CSS и т. д.). Это ускорило процесс… но теперь этот закрытый ключ (1) является общим и (2) хранится в открытом виде, по общедоступному URL. Это, э-э, пугает
Поэтому я сказал, что нам нужно спросить команду Discourse о последствиях для безопасности этого обходного пути. Я вижу два основных варианта:
Если этот закрытый ключ используется «только» для шифрования полезной нагрузки, то мы можем с этим смириться, поскольку наше взаимодействие также защищено шифрованием SSL/HTTPS.
Но если знание этого закрытого ключа каким-либо образом позволяет вычислить результирующий ключ User-API, который затем используется для публикации от имени чьей-то учётной записи в Discourse, то такой обходной путь, конечно же, станет неприемлемым.
Мне тоже интересно об этом, так как я начал использовать программное обеспечение, разработанное @owengot. Исходя из того, что написал @tanius, как ты думаешь, это безопасный способ сделать это, @sam?
Да, так делать не стоит. Закрытый ключ должен быть уникальным и конфиденциальным для каждого клиента.
Генерация ключа за 10 секунд — это цена, которую приходится платить. Существуют некоторые JS-криптографические API, которые могут ускорить этот процесс.