Проблема
Я работаю над бэкэндом проекта, который не только потребует предоставления авторизации различными способами (в основном, сеансами для пользователей-клиентов в браузере и JWT для авторизации между компьютерами), но также некоторые довольно детальные права авторизации. Я все еще довольно новичок в веб-разработке, поэтому, следуя некоторым книгам и учебникам, мой шаблон авторизации выглядел следующим образом.
user.routes. js
const auth = {
hasAuthorization : (req, res, next) => {
const authorized = req.profile && req.auth && req.profile._id == req.auth._id
if (!(authorized)) {
return res.status('403').json({
error: "User is not authorized"
})
}
next()
}
}
router.route('/api/users/:userId')
.put(authCtrl.requireSignin, auth.hasAuthorization, userCtrl.update)
Таким образом, в основном мои запросы проходят через связку промежуточного программного обеспечения, каждое из которых может закончить завершение маршрута, не вызывая next()
и устанавливая ответ, скорее всего, 403 или «фальшивый» 404. Если достигнут последний обработчик в цепочке, он возвращает данные, требующие авторизации.
Проблемы:
У меня много проблем с этим двумя основными:
- Единственный способ добавить дополнительные методы авторизации - расширить
auth.hasAuthorization
, чтобы охватить различные методы авторизации. Учитывая то, что я не уверен на 100% во всех необходимых шаблонах авторизации, это может привести к невероятной потемнению и кошмару. - Доступ предоставляется по умолчанию и должен быть запрещен, я не авторизуя доступ для авторизованных клиентов, я отказываю в авторизации неавторизованным. Ложные обработчики авторизации, очевидно, всегда являются проблемой и являются частью программного обеспечения, которое должно быть особенно хорошо протестировано (в зависимости от того, насколько конфиденциальны данные). Однако, используя вышеупомянутый шаблон, может быть очень легко подвергнуть конечную точку несанкционированному доступу. Я предпочел бы запретить доступ по умолчанию и специально предоставить его, когда предоставлен подходящий метод авторизации. На мой взгляд, гораздо вероятнее, что go останется незамеченным, если у вас есть доступ к чему-то, к чему у вас не должно быть доступа, а не к тому, к которому у вас нет доступа.
Мое намеченное решение
Итак, намеченное решение для устранения этих проблем заключается в следующем; вместо использования промежуточного программного обеспечения, которое устанавливает код результата и данные, когда ему не удается найти авторизацию, оно просто изменяет req.authorizationDetails
следующим образом
const auth = {
authorizeByJWT: (req,res, next) => {
if (jwtProvidesAuthorization()) req.authorizationDetails.grantAccess = true
next()
},
authorizeBySession: (req,res, next) =>{
if (sessionProvidesAuthorization()) req.authorizationDetails.grantAccess = true
next()
}
}
Используя это, я мог бы просто связать авторизацию Middleware:
router.route('/api/users/:userId')
.put(auth.authorizeByJWT, auth.authorizeBySession, userCtrl.update)
А затем проверьте req.authorizationDetails
в конечном обработчике, где я действительно хочу вернуть данные:
function update(req,res){
if (!req.authorizationDetails || !req.authorizationDetails.grantAccess){
res.status(304)
res.json({"message": "Access denied"}
}
let res = {}
//.... get the result from database etc...
res.json(res)
}
У меня нет опыта
Потому что у меня нет большой опыт, и это первый проект, который имеет несколько масштабов, я хотел бы узнать мнение некоторых людей, которые имеют немного больше опыта, чем я. Этот подход кажется функциональным и целесообразным для полного удовлетворения моих требований (различные методы авторизации, детальная авторизация, по умолчанию отказано)? Есть ли какие-либо риски безопасности? Я заново изобретаю колесо / есть ли библиотека, которую я должен использовать, которая делает это лучше, чем я когда-либо мог? Есть ли другие вопросы, которые я мог бы не рассматривать?
Я понял, что этот пост стал довольно длинным, и на самом деле он не рассматривает конкретную проблему c, а скорее требует общего руководства, так что если вы сделали это это далеко, спасибо за ваше время. Я очень ценю, если некоторые из вас готовы дать мне какое-то руководство.