質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

解決済

3回答

6422閲覧

APIの認証方法と公開について

twin_bird

総合スコア230

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

0グッド

3クリップ

投稿2016/09/21 18:43

編集2016/09/22 05:44

jsonを返すAPIをつくっています。

APIの認証には、ヘッダにトークンを投げ、サーバーサイドのミドルウェアでトークンをチェックするという方式を取っています。

公開を想定したAPIなのですが、セキュリティについて分からないところがあります。

このAPIを自アプリケーション内で使用する際、アドミン用のトークンをヘッダに含めているのですが、それだとアドミン用のトークンを公開してしまうことになり、APIに認証を設ける意味がないと気づきました。

APIを公開する際には認証を必要としたいので、利用するユーザーそれぞれにAPIトークンを発行したいのですが、自アプリケーション内でAPIを安全に利用するにはどういう対策がありますでしょうか?

公開用とアドミン用のAPIを別に作成する必要があるのでしょうか??

追記

追記: バックにはLaravel、フロントはReactを使っています。自作APIを利用するときは、基本的にはReactでAPIを叩いています。

追記: 皆様、有益な回答ありがとうございます。ググっても中々実装例が出てこなかったのでとても助かります。ただ、幅広い意見をお伺いしたいので今しばらく回答を募集中のままにさせていただきます。

改めて質問内容を整理します。

Laravelでアプリケーションを開発しており(以下、Laravel Appとします。Wantedlyのようなサービスです。)、「Laravel App内で使用すること」と「外部のクライアントに利用してもらうこと(外部クライアントが開発している別のアプリケーション等に利用してもらう、など)」を目的としたAPIを作っています。

このAPIを利用するには、ヘッダにLaravel Appが発行するユーザー(Laravel Appの利用者かつ登録者)それぞれが保持するAPI Tokenを含めてPOSTすることでLaravel APPのミドルウェアが認証処理を行い、レスポンスを返してくれます。

外部のクラアイントがAPIを利用する分には、このAPI Tokenでの認証方法で良いと思います。(回答者の方のご指摘通り、Tokenのチェック方法に留意する点はまだありますが・・)

しかし、この認証方法を設けてしまうと、Laravel App自身がAPIを使用することが難しくなってしまいます。
例えば、Laravel Appが自身がAPIを利用するためのアドミン用のAPI Tokenを用意しても、ヘッダ情報にAPI Tokenを含める必要があるため、Larave Appを利用する全てのユーザーにアドミン用のAPI Tokenが公開されてしまいます。

上記の利用目的において、APIの認証方法はどのようにすべきでしょうか?

考えている方法

  • 公開用と内部で使用する用でAPIを分ける。内部で使用する用は非公開にする。

  • アドミン用のAPI Tokenを利用せず、ユーザー(Laravel Appの利用者かつ登録者)のAPI Tokenを利用させる。本来、API Tokenは外部の別のアプリケーションの開発等に使用してもらうためのものを想定していたが、Laravel Appを利用する際も使用する仕様にする。

API TokenはLaravel Appに登録した時に自動で発行、いつでもリフレッシュ可能なものとする。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

認証の安全性を考えるときには鍵の運用管理方法を考える必要があります。
ですから、API を呼ぶのが Web UI (=ブラウザやハイブリッドアプリ)からなのか、何かの自動処理システムからなのかによって話が異なります。

Web UI の場合であれば、通常の Web 認証を行い、その Cookie で認証すべきでしょう。毎回ログイン手続きがめんどくさいというクレームがでるのであれば、Cookie の無通信タイムアウトを長めにする手もあります。

UI ではない、システムから呼ばれるのであれば、利用者(あるいはクライアント側のシステム管理者)毎にトークンを発行する必要があるでしょう。そのトークンを他者に盗まれないようにするのは利用者の責任となります。また、利用者はそのトークンが盗まれた可能性が出た時点で速やかにサーバのシステム管理者に報告するよう約束してもらう必要があります。APIの提供側はトークンが盗まれた可能性がある場合に、そのトークンだけを速やかに無効にする機能が必要です。

また、API 呼び出し時にトークンをそのまま付けると、通信経路上やブラウザのキャッシュメモリから一個でも盗まれると(あってはならないことですが)、ずっと使えてしまうので、トークンをそのまま渡すのではなく、APIの内容に発信時刻、ソルトを添えてダイジェストメッセージを作成し、これをトークンの値でハッシュして署名します。サーバ側で同じ操作を行い、同じハッシュ値であればそれを作った人がそのトークンを持っていることが担保できます。

投稿2016/09/22 04:46

mit0223

総合スコア3401

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

twin_bird

2016/09/22 06:21

回答ありがとうございます。 色々混乱していて回答内容をすぐに飲み込めなかったのですが、Cookieで認証させれば解決する気がしました! API呼び出し時の工夫は見逃していたのでこちらも見直してみようと思います。
guest

0

クライアント側のJavaScriptファイルなどにあらかじめトークンをハードコーディングし、それを配布するともちろんダメです。

認証(ログイン)機能を設け、認証に成功したらトークンを発行し、トークン内にユーザ情報などを埋め込み、サーバ側で秘匿な状態にしてある鍵で署名し、SSL通信でやりとりすれば、ユーザー側での改ざんと通信経路上におけるトークンの流出は防げます。具体的にはJWT+SSL通信でよいのではないでしょうか。

ただしそのようにしてもクライアント側に渡った後のトークンの盗難は防げません。(たとえばPCロックせずに離籍したときに他人がブラウザ開いてローカルストレージに保存してあるトークンを盗むなど)
有効期限を設定し、期限が切れたら再ログインしてもらう…ということになります。リフレッシュトークンを発行してもそれが盗まれたら…と考えるとキリがありません。

過去の私の回答でも考察してるのでこちらもどうぞ。
また私もこの辺り色々考えすぎて頭を痛くした経験がありますので、有識者の方の回答を私も伺ってみたいところです。

投稿2016/09/21 19:23

guest1213

総合スコア306

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

twin_bird

2016/09/22 06:23

回答ありがとうございます。 JWTというのは知らなかったです。調べてみます。 過去の投稿も拝見しました。 トークンの受け渡しのセキュリティについて勉強不足な気がしたので、調べてみます!
guest

0

自己解決

mit0223さんの回答が解決方法に近かったのですが、自分なりに解釈して解決したので、こちらに解決方法を投稿します。

アプリケーション内部でのapiの利用方法については、ログイン手続きと同じCookieを利用した認証方法を取りました。
Laravelのログインチェックのやり方に沿って、ミドルウェア内でログインチェックを行うようにしました。

外部からの利用に関しては、API Tokenをヘッダに含める方式を継続して採用することにしました。こちらは安全性をより高める為の実装(署名の工夫など)も検討してみようと思います。

なお、API Tokenによる認証もミドルウェアで行うように実装しました。
従ってミドルウェアではCookie認証とAPI Tokenによる認証のどちらを利用するかの条件分岐を含くめました。
結果的に内部からAPIを叩く必要がなくなりました。

よくよく考えれば単純でシンプルな解決方法でした笑
APIを叩くことにとらわれていましたw

投稿2016/09/22 10:39

twin_bird

総合スコア230

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問