web-dev-qa-db-ja.com

JavaScriptクライアントからのAPI REST API

私はPHP REST JavaScriptクライアントから利用されるAPIを構築していますが、認証側とアクセス側を実装する方法を考える上でいくつかの問題があります。 JavaScriptライブラリを使用する複数のアプリケーションがあり、これらのアプリケーションと対話して対話するために開発しますが、それぞれにAPIキーを提供するので、問題はありません。

私が混乱し始めるのは、これらのサイトのユーザーに私のアプリケーションを認証させる方法です。この外部サイトにユーザーのアカウントとパスワードの情報を保存するのは悪い考えのようです。そのため、アプリケーションのユーザーのアカウント情報を要求するログインウィジェットをJavaScriptライブラリに含める必要があります。

そこで認証が成功した場合、私はREST APIで作業しているため、クライアント側のCookieなどに取得したトークンを保存する必要があります。外部サイトのすべてのページでアプリケーションに再度ログインしますが、ユーザーが外部サイトからログアウトし、別のユーザーが同じブラウザーからログインするとどうなりますか?JavaScriptライブラリに関する限り、古いユーザーはCookie /トークンの有効期限がまだ切れていないため、アプリケーションにログインしたままになります-前のユーザーのセッションが終了したときにCookieをクリアするにはどうすればいいですか?または、完全に正しいパスから外れていますか?

だから、私はプロセスが次のようなものになると考えています:

var token; // Some hashed string containing an expiration date and user id
var apiKey = '123abc';

// Read the cookie and check if it already contains the token
token = readCookie('token');
if (token == '') {
    // get username and password from user through some Prompt

    var request_data = {apiKey: apiKey, user: username, pass: password};
    $.post('https://service.com/api/user/login', request_data, function(data) {
        token = data;
        document.cookie = "token=" + token;
    });
}

...

var get_data = {apiKey: apiKey, token: token};
$.get('http://service.com/api/<object>', get_data, function(data) {
    // Do something with data
});

申し訳ありませんが、いくつかの質問がここに埋もれています。主な理由は、トークンをクッキーに保存している場合、ユーザーが外部アプリケーションからログオフするときにトークンがクリアされるようにするにはどうすればよいでしょうか?または、Cookieに保存するべきではない場合、クライアントにユーザーの状態を認識させるにはどうすればよいですか?

22
lightstrike

これを読むことをお勧めします 非常に良いブログ投稿 RESTful APIの保護について。

(リンクが機能しない場合-すでに一度機能しなくなっており、archive.orgから取得する必要がある場合-PDFこのページのレンダリングはここからアクセスできます: https://www.ida.liu.se/~TDDD97/labs/hmacarticle.pdf 。)

注:上記のブログ投稿で提供されているソリューションはJavascriptクライアントから保護されていないため、私の答えはトピック外です。実際、ほとんどの場合、REST APIをサーバー側で保護する方法を説明しています。

41
Epoc

「混乱し始めるのは、これらのサイトのユーザーにアプリケーションを認証させる方法です。この外部サイトにユーザーのアカウントとパスワード情報を保存するのは悪い考えのようです;」-

REST APIを使用する場合、これを処理する最良の方法は、ドメインによって制御されるか、ユーザーが入力したユーザー資格情報を介した外部パスにかかわらず、クライアント(Webページ、モバイルアプリ)ログインページ)。認証の面倒を見るログイン/ログアウトAPIがあります。

ログインAPIが認証されると、クライアント側の暗号化されたCookieに保存できるトークン(一方向のハッシュで、ユーザーの好みが何であれ)を返します。このようにして、クライアントはユーザー資格情報を直接処理しません。トークンは、いつでも有効期限が切れるように設定されています。

以降のすべてのREST API呼び出しでは、クライアントはこのトークンをAPIへのリクエストとともに送信します(ログイン/ログアウトAPIとは異なります)。APIはおそらくローカルキャッシュ( REST Server)で、これが有効なトークンであるかどうかを確認します。見つかった場合は要求を受け入れ、そうでない場合はエラーをスローします。

トークンの有効期限が切れる前にユーザーがログアウトすると、ログイン/ログアウトAPIはこのトークンをローカルキャッシュから削除し、クライアントはセッション/ Cookieを削除する必要があります。

これにより、資格情報がクライアント側で渡されることはありません。

そしてもちろん、SSLおよびHTTPダイジェストによって、移動中のデータのセキュリティも達成する必要があります。

8
Kingz

別のホスト名から自分のホスト名にクロスドメイン移動するプライベートAPI(ユーザーテーブルがある)の場合、上記に同意し、ユーザーに与えることができる単純な(SSL)ログイン/ログアウトを提案します(またはドメインからCookieを削除します。

パブリックAPIの場合(たとえば、だれでもAPIキーを取得できます)、上記の回答のブログ投稿でメソッドを使用することをお勧めします。

JavaScriptクライアントについては、 https://github.com/jpillora/jquery.rest をお試しください。不足している機能がある場合は、機能リクエストを送信するか、必要に応じて投稿してください:)

1
jpillora