web-dev-qa-db-ja.com

クライアントがSQLを使用してDBに直接クエリできないのはなぜですか?

最新のWebアプリケーションの多くがサーバーからJSONデータを消費するだけであることを考えると、SQLのクエリ言語を使用するだけでなく、REST apiを使用することのポイントは何ですか?

今日、人々はGraphQLを使い始めています。私が理解していることから、クライアントからサーバーへのクエリ言語は、サーバーからデータベースへのクエリに変換されます。

クライアントにデータベースで任意のコードを実行させたくないと思います。しかし、スパム行為のあるリクエストを回避するために、レート制限とタイムアウトを設定して、厳しく制限されたデータベースユーザーを介してクエリを実行するようなことはできないのでしょうか。

3
yawn

データベースへの直接SQLアクセスを提供することは可能ですが、一般的には賢明ではありません。

  • データベースを公開しなければなりません。これだけでは、攻撃対象とデータ損失の可能性が高まるため、不安になります。

通常の構成では、イントラネット上のDBと [〜#〜] dmz [〜#〜] 内のWebサーバーを保持します。次に、Webサーバーをホワイトリストに登録してDBに接続できます。

  • データへの不正アクセスや変更を防止し、一貫したデータモデルを確保する必要があります。ユーザーがデータベースを破壊することはできません。さまざまなユーザーがさまざまなレコードにアクセスできるため、エンドユーザーごとに1つのデータベースユーザーアカウントを作成する必要があります。データビューをこの権限モデルに適合させるために、データベースビューとストアドプロシージャのシステムを開発する必要があるかもしれません。

    通常のWebアプリは、サーバー上のWebアプリケーションコードの権限をチェックするため、データベースの権限モデルに制限する必要はありません。これにより、より適切な粒度で許可モデルを許可できます。データベーステーブルの代わりに問題ドメインの概念。このようなスキームは、はるかに単純になり、したがってより安全になります。

  • 送信される特定のSQLクエリを制限できません。クエリは最適化されていないため、パフォーマンスが非常に高くなります。データベースが明示的なサポートを提供しない限り、キャッシュやレート制限を追加することはできません。

    対照的に、Webサーバーで使用するクエリを調整し、多数のキャッシングテクノロジーを使用できます。

  • ユーザーがDBに直接接続すると、データベースがアプリケーションプラットフォームになります。これは、特定のテクノロジーと特定のデータモデルへの実質的なロックインを表しています。データベースサーバーのスケーリングは、アプリケーションサーバーのスケーリングよりも困難です。

    これとは対照的に、ほとんどのWebアプリケーションは、データベースとアプリケーションロジックを異なるサーバーで実行するだけで、デフォルトである程度のスケーラビリティが得られます。

これらすべてを念頭に置いておくと、データベース中心のアプリケーションを作成することができます。これは良いアプローチです。すべてのユーザーを信頼できるイントラネットアプリケーションの場合。しかし、かなりの問題があるため、これは一般的にはお勧めできません。

Webサーバーがデータベースサーバーの半分になるため、GraphQLは奇妙です。ただし、カスタムセキュリティモデルを実装し、キャッシュを実装し、生のSQLよりも便利なAPIを提供する可能性があります。

「本当の」REST API(つまり、GraphQLではない)は概念的に非常に単純であり、セキュリティチェック(エンドポイントごとに1つまたは2つのif条件)を非常に簡単に実装でき、非常に簡単です。 (GraphQLが対処する)それらの欠点は、必要以上のデータを取得することが多く、リクエストごとに1つのリソースしか取得できないことです。

8
amon

直接SQLアクセスよりもRESTful APIを選択する主な理由は、それが変更する実装への静的インターフェースを提供することです-データの一部がファイルシステムを介してアクセスされてもAPIは変更されませんまたはメッセージングキュー。同様に、必然的にデータベースを重大な変更を加えたバージョンにアップグレードする必要がある場合、どのクライアントも変更する必要はありません。

別の利点は、単純なクエリ/応答形式です。 JSONの基本を学ぶ5分と、データベースクライアントを作成する日または週と比較してください。

データベースのもう1つの大きな問題はアクセス制御です。誰が何にアクセスできるかだけではありません。データベースに複雑なレート制限をどのように記述しますか?また、個人的なメッセージをだれに誰に送信できるかなど、アプリケーション固有の複雑なアクセス制御をどのように表現しますか?これらをデータベースで表現するのは可能だと思いますが、汎用プログラミング向けの言語で表現する方がはるかに簡単です。

3
l0b0

あなたのアイデアはクールに聞こえますが...

SQLアクセスを提供することは、車のキーを見知らぬ人に渡すようなものです。それにはいくつかの問題があります:

1)セキュリティ-データベースにクエリを実行できる場合、テーブルを作成したり、データを挿入したりすることができます。一部のデータベースには、公開を制限できるようなセキュリティ機能がありますが、これを適切に実行し、アクセスするはずのないものを誰かがクエリできないようにすることは非常に困難です。

2)サービス拒否-サーバーを効果的にオフラインにするリクエストのフラッドまたは複雑なクエリのいずれかと簡単に結びつけることができます

Graphqlがこれらの課題にどのように対処し、しかも安全であるかを疑問に思う必要がありますか?

2
Mikkel

まず、API(RESTを含む)は、データベースからのデータの使用に制限されていません。これは、いくつかのアプリケーションから整理されたコードを呼び出すことを意味します。データベースに関連している可能性がありますが、データベース以外のアクティビティも実行できます。アクチュエータを制御したり、センサーデータを読み取ったり、入力に基づいて複雑な式を計算したりします。

クライアントがデータベースに直接アクセスできないようにするもう1つの理由は、追加のセキュリティ層です。エンドユーザーに公開されるシステムは潜在的に悪用される可能性があることはよく知られています。危険にさらされる可能性があります。そして、データベースと直接やり取りしているシステムを危険にさらすことができれば、それはセキュリティ上のゲームオーバーです。この攻撃者は、機密データにアクセスし、データを改ざんし、データを削除することができます。

保守性の観点から見ると、データベースをクライアントから分離すると、次のような設計が簡素化されます。

  1. クライアントを変更せずにデータベースを変更できます
  2. クライアントを変更せずにクエリのバグを修正できます
  3. クライアントを変更せずにテーブル構造を変更できます
  4. (およびボーナス)古いバージョンのクライアントに下位互換性を提供するために、APIメソッドの複数のバージョンを保持できること。
1
A.Rashad