В большинстве сценариев вы хотите, чтобы пользователь мог иметь доступ к объектам в базе данных, созданной самим пользователем. Например, если есть календарь, который был создан User1, то только пользователь1 должен иметь возможность читать, обновлять или удалять этот конкретный календарь и его содержимое в базе данных. Речь идет не о авторизации вообще - в моем проекте уже есть компонент авторизации на основе ролей, который проверяет, принадлежат ли пользователи роли "calendar-editor", но не проверяет, разрешен ли конкретному пользователю доступ к конкретный календарь.
Таким образом, в конечном итоге должно быть проведено сравнение между идентификатором пользователя текущего запроса и идентификатором пользователя, который представляет владельца запрошенного календаря. Но мне интересно, где это сделать. Мои мысли:
-
Я мог бы сделать это на уровне DAO. Но тогда каждому DAO-методу нужен дополнительный параметр, который представляет идентификатор пользователя, который делает эти методы более подробными и уменьшает повторное использование.
например.
def findCalById(id: Int): Future[Option[Calendar]]
становится
def findCalById(id: Int, ownerId: Int ): Future[Option[Calendar]]
Преимущество заключалось бы в том, что проверка разрешения в основном выполняется на уровне запроса, что означает, что если у пользователя нет доступа к календарю, календар не возвращается из базы данных. Но опять же: если в некоторых случаях календар не возвращается, как вы различаете календар, который не существует, и существующий календарь, к которому текущий пользователь не может получить доступ? Два разных сценария, которые дают тот же результат.
-
Другой вариант может заключаться в том, чтобы сохранить DAO из этого и выполнить проверку на уровне сервиса или что-то подобное. Это будет означать, что проверка выполняется ПОСЛЕ того, как запрошенный календарь возвращается DAO. Этот подход звучит более гибко, чем другой, но это также означает, что если пользователь не имеет доступа к запрошенному календарю, запрошенный календарь по-прежнему потребляет полосу пропускания и память, поскольку он извлекается из базы данных в любом случае.
Возможно, есть дополнительные варианты, которые я даже не рассматривал. Есть ли лучшие методы?
Btw: в моем веб-приложении нет календарей, это просто пример, иллюстрирующий проблему.