のーずいだんぷ

主に自分用メモですが、もしかしたら誰かの役に立つかもしれません

chaliceでapi-key認証のAPIをつくる

何をしようとしたのか

タイトルの通りPythonのサーバレスwebフレームワークchaliceを使用して、AWS環境にREST APIを構築しようとした。

AWSにRESTAPIを構築する方法として、API Gatewayを使用するのが一般的であるが、その際に気になる点の一つにアクセス制限があると思う。

API Gatewayではありがたいことに認証(認可)には複数の方法が用意されており、またこれらの殆どをchaliceから簡単に利用できる。

認証方法の一つにAPI-keyと呼ばれる認証方法があり、これは外部に公開するREST APIには必須の機能なので備忘録を兼ねて紹介する。

API GatewayのAPI-key認証について

  • ベーシック認証のようにhttpヘッダーにキーを指定してリクエストすることができる
  • 一般的なAPIサービスのようにキーごとに使用回数制限を課すことできる。
  • APIキーはAWSマーケット?的なやつで販売することができる。(やったことないが、UI作りたくないので個人でぜひやりたいAWS doc
  • 実は認証方法としては弱いため、単独での仕様は非推奨。IAM等と併用したほうがセキュリティてきに良い。

chaliceのスモールアプリでREST APIを作成する。

chaliceアプリケーションの作成

chalice持っていいない場合は以下でインストール

$ pip install chalice

もしAWS-CLIのプロファイルを未作成であればここで作成しておこう。

$ pip install aws-cli
$ aws configure
....continue aws profile setting

ようやくアプリケーションを作成する。 helloworldは任意のアプリケーション名で良い。

$ chalice new-project helloworld

そしたらプロジェクトファイルhelloworld内にある、app.pyを編集しよう。 以下でスモールアプリケーションが作成完了した。

from chalice import Chalice
app = Chalice(app_name="auth_test")
@app.route('/apiKeyAuth/', methods=["GET"], api_key_required=True)
def auth_test():
    return {'auth': "success"}

簡単にアプリケーションについて説明すると…

  • このコードはLambda関数として保存される。
  • https://<自動生成されるドメイン名>/<ステージパス>/apiKeyAuthに対してGETメソッド(ホントはOPTIONも)のみを受け付けるAPIを作成した。
  • @app.route()デコレータ直下にあるメソッドが、このパスのリクエストに対するエントリポイントとなる。
  • 上記のURLに対してリクエストが来ると、API GatewayがLambdaでも解釈できるようにリクエストをパースしてくれる。
  • 今回は単純にjson形式で{'auth':'success'}と帰ってくるようなAPIを作成した。(def auth_test()がじっこうされるので)

  • そして今回の目的であるAPI-keyによる認証の有効化は@app.route()デコレータの引数に渡している、api_key_required=Trueで設定されている。

chaliceアプリケーションをデプロイする。

ここがある意味chaliceの真骨頂。以下のコマンドでAPI GatewayとLambda関数の設定が完了してしまう。

chalice deploy
...
Creating deployment package.
Creating IAM role: auth_test-dev-api_handler
Creating lambda function: auth_test-dev
Creating Rest API
Resources deployed:
  - Lambda ARN: arn:aws:lambda:ap-northeast-1:***********:function:auth_test-dev
  - Rest API URL: https://**********.execute-api.ap-northeast-1.amazonaws.com/dev/

ログを見るとRest API URLという項目があると思う。 これが今回生成されたドメイン名となる。(もちろん独自ドメインも設定可能だが、その場合以下記事を参考に設定してみてほしい)

www.nooozui.com

API-keyと使用量プランの作成

ここは微妙にハマりポイントもあるが基本的には簡単。 まずはAPI-keyをコンソールで作成する。

API Gateway - API-key作成画面
API Gateway- API-key作成画面

API-keyとデプロイしたAPIのステージを紐付ける。

API Gateway - API-keyとAPIステージの紐付け
API Gateway - API-keyとAPIステージの紐付け

今度は使用量プランを作成する。

API Gateway - 使用量プランを作成
API Gateway - 使用量プランを作成

最後にAPI-keyを使用量プランに登録する。

API Gateway - API-keyを使用量プランに登録する
API Gateway - API-keyを使用量プランに登録する

実際にリクエストしてみる

認証方法

http-headerのx-api-keyに、API Gatewayで発行したkeyを設定してアクセスできるようにする。 なおAPI-keyの値の入手方法は以下画面より入手可能。

API Gateway - API-keyの値を入手
API Gateway - API-keyの値を入手

curl  https://**********.execute-api.ap-northeast-1.amazonaws.com/dev/apiKeyAuth/ \
--header "x-api-key:fagljr****************************"
...
{"auth":"success"}

無事リクエストが得られた。

ハマるかもしれないポイント(自分はハマった)

今回一から上記を実施すればハマることはないと思う。が、私の場合当初API-keyを作成してからアプリケーションを作成しており、ステージのデプロイができていなかった。 ステージがAPI-keyに登録されていない場合は、認証エラーのレスポンス、403 Forbiddenが返ってくるので注意したい。

参考

chalice.readthedocs.io