twitter icon   twitter icon   rss icon

Linux.com Japan

Home Linux Jp チュートリアル 他のアプリケーション データにアクセスする OAuth クライアントを作成する

他のアプリケーション データにアクセスする OAuth クライアントを作成する

原文は 2015 年 6 月 2 日に掲載されました。

oauth github authorize
OAuth を使うことで、開発者は他サービスのユーザー アカウントにアクセスする独立したアプリケーションを開発できます。たとえば Facebook の場合、開発者は、ユーザーがゲーム内から Facebook のウォールに投稿できるようなゲームを開発することができます。アプリケーションは、ユーザーのクレデンシャルを保持しないので、交信内容はセキュアに保たれ、かつ、ユーザーは、アプリケーションへの許可をいつでも取り消せます。
 
これを実現するために、Facebook、Google、GitHub などのサービスは、OAuth サービスを実装しています。2 種類のコードが含まれています。OAuth 提供側のコード (つまり Facebook 側です)、OAuth クライアント側のコード (つまり Facebook のクレデンシャルでログインする側のサイトもしくはアプリケーションです)。これらのうち、プログラマーは、クライアント側のコード、Facebook などが提供する機能を利用して、ユーザーがログインする側のコードを開発できます。それでは、説明しましょう。
 

OAuth の動き

あるサービスのデータをリソースと言います。たとえば、あるゲームを開発していたとしましょう。そのゲーム内で、ユーザーは、ゲーム スコアを Facebook のウォールで共有できるようにします。そのウォールはリソースと言えます。また、他のユーザーとプレイする時にアイコン表示をするために、アプリケーションはユーザーの写真を利用します。ウォールと写真はユーザーの所有物ですから、ユーザーはリソースの管理者となります。また、別の例として、GitHub にアクセスする Linux ベースのアプリケーション開発を考えてみます。ユーザーの gist を読み出す時、これはリソースと考えられます。
 
OAuth への関わり方には、3 つのパターンがあります。
  • エンド ユーザー: OAuth の考え方では、リソースの所有者です。
  • ユーザーがログインするアプリケーション: OAuth のクライアントとして機能するアプリケーション。OAuth の考え方では、リソース クライアントです。OAuth アプリケーションとも呼びます。
  • OAuth Provider (提供者): リソース サーバーのことです。
これらをうまく機能させるために、OAuth の開発者は、すべてのプライバシーを保護できるシステムを構築しようと考えました。たとえば、アプリケーションがユーザーのウォールを参照する時、ユーザーは、アプリケーションがユーザー名とパスワードを保持するとは思いたくありません。また、悪意を持った開発者がユーザー名とパスワードを盗むとも思いたくありません。そこで OAuth は、ユーザーがアプリケーションに、そのようなことができる権限は与えますが、すべての権限 (たとえば、外部にメールを送り、フレンド リクエストを送信する) を与えないようにします。さらに、ユーザーは、いつでも権限を取り消せます。
 
これを実現するために、OAuth は、いくつかのステップを用意しました。まず、Web ベースのアプリケーションの利用者の観点から見てみましょう。
  1. 利用者がアプリケーションを開始します。アプリケーションが Facebook アカウントへのアクセスを要求します。

  2. 許可したら、Facebook へのログイン画面が表示されます。画面には、同時にアプリケーションが許可されている内容 (友人リストの参照、ウォールへの投稿) が表示されています。

  3. これで、アプリケーションは、自由にウォールへ投稿します。

 
しかし、必要であれば、ウォールへの投稿権限を取り消すこともできます。さらに、Facebook へログインし、アプリケーション設定から、ウォールへのアクセス権限を取り消すことができます。
 
アプリケーション開発者の視点から見てみましょう。
 
  1. アプリケーション開発者は、ユーザーの Facebook アカウントにアクセスする旨、ユーザーに許可を求めるアプリケーションを開発します。そのため、ウォールへの投稿などのアクセスしたいリソースの一覧を用意します。

  2. ユーザーの同意が得られたら、Facebook へのログイン スクリーンをユーザーに送ります。ログイン スクリーンは、新規に画面を開き、ユーザーにログインを要求します。その後このページは、指定と異なるリソースへのアクセス権限をアプリケーションに与えるか、ユーザーに確認します。もし、ユーザーが既にログインしている場合は、この画面は省略されます。

  3. ユーザーがログインし、権限を与えることに同意したら、画面は、開発者のサイトに移動します。移動先で利用するコードが送付されます。

  4. Web サーバーで (ブラウザの中ではなく) そのコードを使用し、Web サーバーから Facebook サーバーに、先のコードをトークンに変換するように要求します。

  5. トークンを含む REST フル リクエストを用いることで、リソースを参照できます。

 
それでは、OAuth Provider と OAuth クライアントの通信を行うコードを書いてみましょう。OAuth Provider が必要です。持っていない場合は、OAuth 2 site に例があります。また、ここで利用する OAuth は新しいバージョン 2 です。
 

OAuth  クライアントを開発する

OAuth クライアントを作成します。このアプリケーションは、ユーザーに、ある provider にログインしてもらうものです。Provider として、Facebook の代わりに GitHub を利用します。OAuth のドキュメントには、ユーザーの代理として GitHub にログインするなどの何ができるかが、書かれています。しかしこれは、本当にできることとは少し異なります。それよりもユーザーがアプリケーションから GitHub アカウントを管理できる、と言ったほうが正確です。本質的には同じことですが、より正しいあり方です。(しかし、特定のアプリケーションは、Facebook などで問題を引き起こしています。たとえば、ユーザーの知らないところで、ゲーム リクエストが送信されたりしています。ユーザーは、最初にログインした時に許可しているはずなので、ユーザーの責任ですが、本人は自覚していません)。
 
GitHub は、参照可能なリソースを用意しています。API Directory に記載されています。OAuth は、参照のための API に、挿入するトークンを提供できます。トークンを利用して、リソースにアクセスします。ドキュメントを見ると、GitHub サイトでできることのほとんどが、GitHub の API を通して可能なことがわかります。その気があるならば、GitHub のリポジトリを管理する別のサイトを構築できるのです。
 
GitHub を含む OAuth Provider は、アプリケーションの登録が必要です。そのために、クライアント ID とクライアント シークレットの、2 つのコードが必要です。アプリケーション登録時に、この2つのコードが入手できます。クライアント ID は、ブラウザから、アプリケーションを呼び出すコード内に入れ込みます。このコードはユーザーから見えます。クライアント シークレットは、秘密にしておく必要があります。ブラウザへは送りません。この 2 つのコードで、アプリケーションを特定します。2 つのコードをトークンと結合することで、ユーザーを識別できます。この 3 つすべてが揃うことで、GitHub は、呼び出しが正しく認証されていることを知るのです。
 
それでは始めましょう。OAuth がユーザーの代理として、API 内で利用するトークンを入手するための方法であることを理解していれば、そんなに難しいものではありません。一旦トークンを入手したら、実際に実行すべきことに集中します。ここでは OAuth に焦点をあて、API に関する部分は最小限にとどめておきます。これで他の OAuth provier にアクセスするときのコードに応用できます。
 
次のステップに従ってください。

ステップ 1. アプリケーションを登録します。

ステップ 2. ユーザーにログインを促すコードを書きます。

ステップ 3. トークンを処理して、GitHub から e メール アドレスと gists を入手するためにトークンを用いるコードを書きます。

その前 (ステップ 0 と言うべきでしょうか) に、使用言語を決めて、スターター Web アプリケーションを作成します。私は最近 node を利用しているので、node express を使ったアプリケーションにします。そのために、web サーバーにシェルをロードします。アプリケーション開発用のディレクトリを作成します。まず、以下を実行します。
npm install express

次に

express --hbs -f 

を実行して、アプリケーションを作成します。最後に、node モジュールを初期化します。

npm install

Web サーバーのドメイン名とポート 3000 を利用することを指定します。

それでは実際のステップに移ります。
 

ステップ 1. アプリケーションの登録

まず GitHub にサインアップしましょう。(ここの読者は、多分大丈夫でしょう)。
GitHub's developer application page に行ってください。
oauth github regsitration
右上の Register New Application ボタンをクリックします。
 
Application Name を選び、アプリケーション用の URL を入力します。説明を追加します。"最初のアプリケーション”くらいで構いません。GitHub は、皆さんが勉強のために利用していることは知っています。最後に、アプリケーション コールバックを入力します。これは、ユーザーがログインした後にリダイレクトされるページの URL です。ユーザーは、まず GitHub のログインとアプリケーションの許可画面へ行き、すべての入力が完了すると、アプリケーションの画面にリダイレクトされます。それが、ここで指定するページのことです。私は、自分のドメインとポート 3000に /callback を追加したものを指定しました。つまり、コールバックに応答するコードを /callback 内に書き込んでおく必要があります。(皆さんが指定するときは、/callback だけでなく URL 全部を書いてください。)
 
アプリケーション イメージを追加することもできます。しかし、テスト用なので、そこまでする必要はありません。最後にページ下にある緑色の "Register Application" ボタンをクリックします。画面が以下のようになります。
 
oauth github ID
画面右上に、クライアント ID とクライアント シークレットが表示されています。(スクリーンショットでは隠してありますが、16 進表示されています)。GitHub はこれらを記憶しています。いつでも、この画面に戻って、確認できます。application page に行き、該当するアプリケーションを選択するだけです。
 

ステップ 2. ログイン ページの作成

OAuth に集中するため、画面のデザインは気にしないことにします。Node express は、標準の画面を用意しているので、そちらを利用します。views ディレクトリの index.hbs というファイルです。(拡張子 hbs は handlebarsを意味しますが、ここでは handlebars マークアップは利用しません)。index.hbs を開き、すべてを消して、下記の 1 行だけにします。
<a href="/https://github.com/login/oauth/authorize?client_id=abcdefghijklmnop&scope=user:email,gist">Login</a>

abcdefghijklmnop をクライアント ID で置き換えてください。(クライアント ID です。クライアント シークレットではありません。このファイルは HTML ですから、ユーザーのブラウザで見ることができます。)

これで、ログイン画面は完了です。テスト プログラムには充分です。アプリケーションを立ち上げ、ブラウザでその URL を開きます。最新の node express では、アプリケーションの bin ディレクトリから起動し、www と入力します。
 
oauth github login
まず、ログイン画面が表示されます。素っ気ないものです。リンクをクリックすると、GitHub に行きます。アプリケーション ユーザーとして GitHub に接続されているのです。アプリケーションの開発者としてではありません。GitHub の自分のアカウントを利用したとしても、友人が一緒にいて、GitHub にあなたの代わりにログインする場合も同様になるのです。GitHub に既にログインしているかどうかによりますが、GitHub のログイン画面が表示されます。ログイン後、アプリケーションの認証画面になります (本チュートリアルの最初の図)。
 
ここで、アプリケーションに指定リソースへのアクセス権限を認可します。ここで、HTML 中のパラメーターを見直してみましょう。
 
client_id=abcdefghijklmnop&scope=user:email,gist
 
2 番目の指定が、許可内容です。(ユーザーはこれらを変更できます。しかし、エンド ユーザーはリソースに対する権限を変更するだけなので、これは、セキュリティ上の問題になることはありません)。
 
これより先に進み、アプリケーションに権限を与えるためには、コールバックが必要です。
GitHubが、/callback ページに戻したときには、404 エラーが発生します。問題はありません。許可を取り消せば良いのです。許可取り消しは、"developer application" ページに行き、"Authorized Applications" タブをクリックします。アプリケーションの一覧が表示されるので、隣にある "Revoke" ボタンを押します。(アプリケーション開発中に、これを何回もする必要があるでしょう。)
 
 コールバックを作成します。
 

ステップ 3. コールバックの作成

コールバック プログラムは、URL にパラメータとしてコードを追加して、REST 呼び出しを作成し、GitHub API サーバーに渡して、実際のトークンを入手します。(この余分なステップにより、トークンをブラウザに渡してしまうセキュリティ リスクを生じさせないようにします)。入手したトークンを使って、gists を入手するための API を作成します。つぎに、JSON 形式で、ブラウザに送付します。JSON 形式であれば、Web 開発者が、クライアントサイドの Javascript で綺麗なインタフェースを開発できるからです。その部分は、皆さんにお任せします。
 
コールバックは、アプリケーションの app.js ページに追加します。コードを見る前に、コールバックのコードがどのように実行されるかを理解しましょう。ブラウザが、GitHub のログイン・許可画面にリダイレクトされます。処理が成功すると、コールバック ページにリダイレクトされます。URL 中には、トークン入手のためのコードが含まれています。ブラウザは、GitHub ページからリダイレクトされると、URL を Web サーバーに送付します。Web サーバーがリクエストを確認し、コードを入手すると、トークン要求の手続きに移ります。そして、新しく作成したページをプラウザに送付します。
 
app.js ファイルに以下の app.get('/') 関数を入れます。
app.get('/', function(req,res) {
    res.render('index');
});

これは index ページを処理します。処理完了後、以下のコードを入れます。

app.get('/callback', function(req,res) {
    var postobj = {
        uri: 'https://github.com/login/oauth/access_token?' +
            'client_id=abcdefghijklmnop&' +
            'client_secret=xyz1234567890&' +
            'code=' + req.query.code,
        headers: {
            Accept: 'application/json'
        }
    };
    request.post(postobj, function(err, resp, body) {
        // Make sure you include more robust error checking
        var result = JSON.parse(body);
        if (result.error) {
            res.send(result.error_description || result.error);
            return;
        }
        // Use this token to list the user's gists
        var requestobj = {
            //uri: 'https://api.github.com/user/emails',
            uri: 'https://api.github.com/gists',
            headers: {
                Authorization: 'token ' + result.access_token,
                'User-Agent': 'linuxcomtest1'
            }
        };
        request(requestobj, function(err, resp, body) {
            res.send(body);
        });
    });
});

本コードを利用するためには require 文が必要です。以下の 2 つをファイルの先頭に入れてください。

var request = require('request');
var querystring = require('querystring');

ファイルを保存します。request パッケージを追加します。

npm install request

HTTP request ライブラリを追加して、request コールを作成できるようにします。コードに戻りましょう。

最初のコードは、URL 中のコードを権限を得るためのトークンに変換するためのものです。"abcdefghijklmnop" をクライアント ID で、"xyz1234567890" をクライアント シークレットで置きかえてください。コード引数は、入力された URL に含まれています。これは、GitHub が設定します。これで完了です。トークン入手用の URL https://github.com/login/oauth/access_token の呼び出しができました。application/json を要求する ccepts ヘッダーを追加しています。しかし、他のものは試していません。特に不要だと思います。サーバーから GitHub を呼び出します。ユーザーのブラウザは、この呼び出しをしません。大量の JSON が戻ってきます。文字列ですので、処理ができます。何か問題があれば、JSON 中にエラー オブジェクトが含まれています。それにはメッセージが含まれています。簡単にするため、今回はそのままクライアントに渡しています。
 
うまく動作していれば、トークンが入手できます。このトークンで、ユーザーの代理として API を作成できます。GitHub サーバーに別の呼び出しを行う準備ができました。これは簡単です。gists を要求します。URL はどこでしょうか。GitHub ドキュメントに記載されています。ここが gists のページです
 
ヘッダーに注意してください。これはオプションではありません。"token" の次に、空白、そして、実際のトークンを付けます。次のヘッダーは、GitHub 特有のものです。アプリケーション名からなる User-Agent ヘッダーが必要です。履歴確認と保守のために必要です。(入れておかないと、エラーになります)
 gists 要求が戻ると、それをブラウザに戻しています。大量の JSON ですが、どのように処理するかは、皆さんが決められます。 コード内に、e メール アドレスを入手するコードを入れました。GitHub に登録されている e メール アドレスを入手します。関連する行のコメントを外すことで実行できます。
 

API コールの終わり方 

これで全部です。OAuth  は、ユーザーのトークンを入手するための手段です。その後は、通常の API 呼び出しを作成することと同じです。ここで言わなかったことがひとつだけあります。呼び出しの繰り返しです。トークンを既に入手しているので、再利用できるという点だけが異なります。どうすれば良いのでしょうか。お任せします。サーバー上のデータベースに格納することもできます。暗号化しない限り、クッキーに格納することは良くないでしょう。ユーザーに戻してしまうことになります。次はどうしますか? 他のさまざまな API 呼び出しを勉強しましょう。そして、OAuth を利用している他のサービスを使ってみましょう。それでは。
Linux Foundationメンバーシップ

30人のカーネル開発者

人気コンテンツ

  1. Today's Linux 2018/11/28 2018年 11月 27日
  2. Today's Linux 2018/11/29 2018年 11月 28日
  3. Today's Linux 2018/12/03 2018年 12月 02日
  4. Today's Linux 2018/12/04 2018年 12月 03日
  5. Today's Linux 2018/12/06 2018年 12月 05日

Linux Foundationについて

Linux Foundation はLinux の普及,保護,標準化を進めるためにオープンソース コミュニティに資源とサービスを提供しています

 

The Linux Foundation Japan

サイトマップ

問い合わせ先

サイトに関するお問い合わせはこちらまで

Linux Foundation Japan

Linux Foundation

Linux Training

提案、要望

Linux.com JAPANでは広く皆様の提案、要望、投稿を受け付ける予定です。

乞うご期待!