Безопасно ли авторизовывать пользовательские модели с помощью `instanceof` в JavaScript / TypeScript?

#javascript #typescript #adonis.js #lucid

#javascript #машинописный текст #adonis.js #ясный

Вопрос:

Допустим, у меня есть 3 модели: Admin, User, Product (я использую классы моделей).

Только администратор может ДОБАВЛЯТЬ, ОБНОВЛЯТЬ, УДАЛЯТЬ продукт, а пользователи могут получать только продукты, поэтому я зарегистрировал промежуточное программное обеспечение ACL для соответствующих маршрутов.

Теперь в моем промежуточном программном обеспечении ACL я хочу авторизовать пользователей, и если они являются АДМИНИСТРАТОРАМИ, я вызову next() метод, в противном случае я отклоню запрос с помощью a 401 .

Я обнаружил, что легко выполнить проверку с помощью instanceof оператора JavaScript:

 const user = await auth.authenticate()

if (user instanceof Admin) {
  await next()
} else {
  throw UnAuthorizedUserException
}
 

await auth.authenticate() возвращает текущего пользователя, отправляющего запрос, будь то пользователь или администратор

Однако я не уверен, что это самый безопасный способ отличить черно-белых администраторов от пользователей.

Теперь мой вопрос в том, правильно ли я это делаю? Какой подход лучше, чем то, что я делаю?

Примечание (если это поможет): я использую Adonis.js модели v5, TypeScript и Lucid

Ответ №1:

Да, вы можете это сделать. Вам нужно быть осторожным с шаблонами наследования, если вы используете этот подход. Возможно, вы захотите добавить свойство роли к объекту user и использовать его для проверки.

пример использования роли prop.

 if (user.role === 'ADMIN') {
  ...
}
 

пример того, как instanceof вызывает у вас неприятные последствия

 class User {}
class Admin extends User {}

const user = new User;
const admin = new Admin;

console.log(user instanceof User); // true
console.log(user instanceof Admin); // false
console.log(admin instanceof User); // true **watch out for this**
console.log(admin instanceof Admin); // true
 

Комментарии:

1. Спасибо, поэтому я должен заглянуть в ORM, чтобы посмотреть, что происходит под капотом.

Ответ №2:

instanceof Оператор проверяет, появляется ли свойство прототипа конструктора где-либо в цепочке прототипов объекта. Возвращаемое значение является логическим значением.

So user instanceof Admin даст положительный результат, если user is Admin или его экземпляр подкласса. Использование этого шаблона очень распространено в мире JS / TS и безопасно, пока auth.authenticate() корректно аутентифицирует пользователей и Admin возвращает тот же authenticate метод класса.

Также в TypeScript instanceof обрабатывается как TypeGuard, поэтому внутри if блока вы можете использовать user его как Admin экземпляр (например, если экземпляр admin имеет больше методов).

Комментарии:

1. Спасибо, поэтому я должен заглянуть в ORM, чтобы посмотреть, что происходит под капотом.