ここでは多くの質問があり、Nodeとpassport.jsのコンテキストで質問されたとしても、実際の質問は、特定のテクノロジーでこれを行う方法よりもワークフローに関するもののようです。
@Keithの設定例を使用して、セキュリティを強化するために少し変更します。
- のWebサーバー
https://example.com
は、単一ページのJavaScriptクライアントアプリを提供します
- のRESTful Webサービスは
https://example.com/api
、リッチクライアントアプリにサーバーサポートを提供します
- Nodeとpassport.jsに実装されたサーバー。
- サーバーには、「ユーザー」テーブルを備えたデータベース(あらゆる種類)があります。
- ユーザー名/パスワードとFacebook Connectが認証オプションとして提供されています
- リッチクライアントはRESTリクエストを
https://example.com/api
- のWebサービスを使用して
https://example.com/api
いるが、のWebサーバーについて知らない他のクライアント(電話アプリなど)が存在する場合がありますhttps://example.com
。
安全なHTTPを使用していることに注意してください。私の意見では、パスワードや認証トークンなどの機密情報がクライアントとサーバー間でやり取りされるため、公開されているすべてのサービスで必要なものです。
ユーザー名/パスワード認証
まず、単純な古い認証がどのように機能するかを見てみましょう。
- ユーザーが接続する
https://example.com
- サーバーは、初期ページをレンダリングする豊富なJavascriptアプリケーションを提供します。ページにログインフォームがあります。
- ユーザーがログインしていないため、この単一ページアプリの多くのセクションにはデータが入力されていません。これらすべてのセクションには、「ログイン」イベントのイベントリスナーがあります。これはすべてクライアント側のものであり、サーバーはこれらのイベントを認識していません。
- ユーザーは自分のログイン名とパスワードを入力して送信ボタンを押すと、JavaScriptハンドラーがトリガーされ、ユーザー名とパスワードがクライアント側の変数に記録されます。次に、このハンドラーが「ログイン」イベントをトリガーします。繰り返しますが、これはすべてクライアント側のアクションであり、資格情報はまだサーバーに送信されていません。
- 「ログイン」イベントのリスナーが呼び出されます。これらのそれぞれは
https://example.com/api
、ページにレンダリングするユーザー固有のデータを取得するために、1つ以上のリクエストをRESTful APIに送信する必要があります。RESTfulであるサービスは、あるリクエストから次のリクエストまでクライアントの状態を維持できないため、Webサービスに送信するすべてのリクエストには、おそらくHTTP 基本認証の形式でユーザー名とパスワードが含まれます。Webサービスは安全なHTTPを使用しているため、パスワードは転送中に安全に暗号化されます。
- のWebサービスは
https://example.com/api
、それぞれが認証情報を含む個々の要求の束を受け取ります。各リクエストのユーザー名とパスワードはユーザーデータベースと照合され、正しい場合はリクエストされた関数が実行され、データがJSON形式でクライアントに返されます。ユーザー名とパスワードが一致しない場合、エラーが401 HTTPエラーコードの形式でクライアントに送信されます。
- すべてのリクエストでクライアントにユーザー名とパスワードを送信させる代わりに、RESTfulサービスで「get_access_token」関数を使用して、ユーザー名とパスワードを取得し、トークンで応答することができます。関連付けられた日付。これらのトークンは、ユーザーごとにデータベースに格納されます。その後、クライアントは後続のリクエストでアクセストークンを送信します。アクセストークンは、ユーザー名とパスワードの代わりにデータベースに対して検証されます。
- 電話アプリなどの非ブラウザークライアントアプリケーションは、上記と同じように動作し、ユーザーに資格情報を入力するように求め、Webサービスへのすべてのリクエストでそれら(またはそれらから生成されたアクセストークン)を送信します。
この例の重要なポイントは、RESTful Webサービスはすべてのリクエストで認証を必要とすることです。
このシナリオでは、追加のセキュリティ層により、ユーザー認証に加えてクライアントアプリケーションの承認が追加されます。たとえば、すべてウェブサービスを使用するウェブクライアント、iOSアプリ、Androidアプリがある場合、認証されたユーザーが誰であるかに関係なく、特定のリクエストのクライアントが3つのうちどれであるかをサーバーに認識させることができます。これにより、Webサービスで特定の機能を特定のクライアントに制限できます。これについては、APIキーとシークレットを使用できます。いくつかのアイデアについては、この回答を参照してください。
Facebook認証
上記のワークフローはFacebook接続では機能しません。Facebook経由のログインにはサードパーティのFacebook自体があるためです。ログイン手順では、ユーザーがFacebookのWebサイトにリダイレクトされ、ここで資格情報が私たちの管理外で入力されます。
それでは、状況がどのように変化するかを見てみましょう。
- ユーザーが接続する
https://example.com
- サーバーは、初期ページをレンダリングする豊富なJavascriptアプリケーションを提供します。このページには、「Facebookでログイン」ボタンを含むログインフォームがある場合があります。
- ユーザーが[Facebookでログイン]ボタンをクリックすると、(たとえば)にリダイレクトされるだけのリンクになり
https://example.com/auth/facebook
ます。
https://example.com/auth/facebook
ルートがpassport.jsによって処理され(参照マニュアルを参照して)
- ユーザーが目にするのは、ページが変更され、Facebookがホストするページに移動して、ログインしてWebアプリケーションを承認する必要があることだけです。これは完全に私たちの制御外です。
- ユーザーのFacebookにログインしてFacebookは今、私たちは次の例passport.jsセットアップ、で構成されていること、バックコールバックURLにリダイレクトして、我々のアプリケーションに許可を与える文書れます
https://example.com/auth/facebook/callback
https://example.com/auth/facebook/callback
ルートのpassport.jsハンドラーは、Facebookのアクセストークンと、ユーザーの電子メールアドレスを含むFacebookからのユーザー情報を受信するコールバック関数を呼び出します。
- 電子メールを使用して、データベースでユーザーを特定し、Facebookアクセストークンを保存できます。
- Facebookコールバックで最後に行うことは、リッチクライアントアプリケーションにリダイレクトすることですが、今回は、ユーザー名とアクセストークンをクライアントに渡して、それらを使用できるようにする必要があります。これは、いくつかの方法で実行できます。たとえば、JavaScript変数をサーバー側のテンプレートエンジンを介してページに追加したり、この情報とともにCookieを返すことができます。(最初に提案したように、URLでこのデータを渡すことによるセキュリティの問題を指摘してくれた@RyanKimberに感謝します)。
- これで、もう一度シングルページアプリを起動しますが、クライアントにはユーザー名とアクセストークンがあります。
- クライアントアプリケーションは、「ログイン」イベントをすぐにトリガーし、アプリケーションのさまざまな部分に、Webサービスから必要な情報を要求させることができます。
- に送信さ
https://example.com/api
れるすべてのリクエストには、認証のためのFacebookアクセストークン、またはREST APIの「get_access_token」関数を介してFacebookのトークンから生成されたアプリケーション独自のアクセストークンが含まれます。
- OAuthではログインにWebブラウザーが必要なため、ブラウザー以外のアプリでは少し難しいです。電話またはデスクトップアプリからログインするには、ブラウザーを起動してFacebookにリダイレクトする必要があります。さらに悪いことに、ブラウザがFacebookアクセストークンを何らかのメカニズムを介してアプリケーションに返す方法が必要です。
これでほとんどの質問に答えられるといいのですが。もちろん、FacebookをTwitter、Google、またはその他のOAuthベースの認証サービスに置き換えることができます。
これに対処する簡単な方法があるかどうか知りたいです。
passport-facebook
。これが機能するようになったら、次のステップは、Passportがどのように機能するか、およびPassportがどのように資格情報を保管するかを理解することです。それをRestifyに接続する(ここで言及した更新バージョンについてはこちらを参照)は、最後のステップの1つになります(またはExpressにRESTインターフェースを実装することもできます)。