どうも、cloudpack の Play で Play しているかっぱ (@inokara) です。
はじめに
Play Framework を公開しようとする場合に素のアプリケーションサーバーでアクセスするか ELB 又は Nginx 等をリバースプロキシとして利用してアクセスすることが出来ると思います。
その際にアプリケーション側で接続元の IP アドレスや User Agent 等を取得したいよねってことで試してみました。
参考
やってみる
アプリケーションを作成
play new hoge
新しい hoge アプリケーションを作りましょう。
HTTP リクエストヘッダを覗くスクリプト
コントローラに HTTP リクエストヘッダを取得して JSON で出力するスクリプトを見よう見まねで下記のように書きました。
package controllers; // JSON 扱う為に必要 import play.libs.Json; import com.fasterxml.jackson.databind.node.*; com.fasterxml.jackson.databind.JsonNode; import play.*; import play.mvc.*; // HTTP ヘッダを扱う為に必要 import play.mvc.Http.Request; import views.html.*; public class Application extends Controller { public static Result ip() { ObjectNode result = Json.newObject(); Request req = play.mvc.Http.Context.current().request(); String x = req.getHeader("X-Forwarded-For"); String p = req.getHeader("X-Forwarded-Proto"); String ua = request().getHeader("User-Agent"); result.put("x-forwarded-for", x ); result.put("x-forwarded-prot", p ); result.put("user-agent", ua ); return ok(result ); } }
JSON を扱う為には以下のような幾つかのライブラリをインポートする必要がありました。
また、今回やりたいことのキモとなる HTTP リクエストヘッダを扱う為には以下のライブラリをインポートする必要がありました。
とりあえず view は用意する必要無いので play run
してしまいましょう。
play run
もしくは play
して run
でもよかばい。正常に起動したら curl
なりブラウザでアクセスして確認してみます。
素でリクエストを投げる
リクエストは以下のように投げます。
client => Play
そして、以下のようなレスポンスを得ることが出来ます。
{ "remote_address": "xxx.xxx.xxx.xxx", "user-agent": "curl/7.30.0", "x-forwarded-prot": null, "x-forwarded-for": null }
“xxx.xxx.xxx.xxx” は接続元の IP アドレスとなります。
ELB 経由でアクセスしてみる
ELB を介したアクセスの場合…
client => ELB => Play
そして、以下のようなレスポンスが得られます。
{ "remote_address": "172.31.14.xxx", "user-agent": "curl/7.30.0", "x-forwarded-prot": "http", "x-forwarded-for": "xxx.xxx.xxx.xxx" }
“xxx.xxx.xxx.xxx” は接続元の IP アドレスとなります。また、remote_address
には ELB の内部 IP が取得出来ています。
ELB => Nginx 経由でリクエストを投げる
さらに間に Nginx 等の Web サーバーを挟んだ場合…
client => ELB => Nginx => Play
以下のようなレスポンスが得られます。リバースプロキシは多段になっていますが、それぞれの IP アドレス(アクセス元を含む)がちゃんとリクエストヘッダ内に書かれていることを Play 側で認識しているようです。
{ "user-agent": "curl/7.30.0", "x-forwarded-prot": "http", "x-forwarded-for": "xxx.xxx.xxx.xxx, 172.31.14.xxx" }
ちなみに、Nginx の設定はこちらを参考にして以下の通り。
proxy_buffering off; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Scheme $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_http_version 1.1; upstream my-backend { server 127.0.0.1:9000; } server { listen 8080; server_name www.mysite.com; location / { proxy_pass http://my-backend; } }
ということで…
なんだかんだで Play Framework で HTTP リクエストヘッダの取得方法について勉強することが出来ましたし、X-Forwarded-for とかの各種ヘッダ周りについての動作を確認することが出来ました。
おやすみなさい。
元記事はこちらです。
「Play Framework で X-Forwarded-for とかの HTTP リクエストヘッダを取得する」