Nuxt generate Laravel Nova on AWSが綺麗にハマった話

@kotamat

  • kotamat
  • SCOUTER CTO
  • サーバー、インフラ寄り
  •  🚴‍♂️
  • Vuefesメンバー

だけkotamats

日本初 紹介免許なしで人材紹介ができる
ソーシャルヘッドハンティング
現在3,000名が登録し身近な転職希望者を
紹介することで報酬が得られます

紹介会社様の収益化に特化した

求人データベース+業務管理ツール
月額課金のみで紹介料を全額受け取れます

2つの人材紹介サービスを展開

新規サービス開発中

今までLaravueでやってきた

新規事業の要件

  • とりあえず最短で仮説検証できるように
  • 今までの技術スタック的にLaravel + Vue.jsが最短
  • リリースのタイミングで必要最低限のCRUDが入っているAdminが必要
    • アカウント発行
    • 事業的に変更が発生しうるマスターデータの編集
    • ユーザが登録した情報の確認

ちょうどLaravel Novaが

リリースされた🎉

CRUDが簡単に作成できる

Eloquentを登録

class Company extends Resource
{
    /**
     * The model the resource corresponds to.
     *
     * @var string
     */
    public static $model = \App\Entities\Company::class;

表示フィールドを登録

    /**
     * Get the fields displayed by the resource.
     *
     * @param  \Illuminate\Http\Request $request
     *
     * @return array
     */
    public function fields(Request $request)
    {
        return [
            ID::make()->sortable(),
            Text::make('Name')
                ->sortable()
                ->rules('required', 'max:100')
            ,
            BelongsToMany::make('Talents')
            ,
        ];
    }

導入方法

  • サイトからライセンス購入
  • zipを当該アプリケーションに設置
  • composer.jsonをいじってパッケージ化

アプリケーションの

ルーティング(理想形)

  • /api/*
    • LaravelのAPIサーバーのルーティング
  • /nova, /nova-assets, /nova-api
    • LaravelのAPIサーバーのルーティング
  • それ以外
    • Nuxt.jsのルーティング

インフラどうやって

構築しよう🤔

インフラ構築指針

  • とりあえず、4XX系はNuxt.jsでレンダリング
  • /apiはポート全開放でもいいが、/nova系に関しては、自社のIPだったり、何かしらのファイアーウォールをはさみたい
  • ファイアーウォールで弾いても、レンダリングはNuxt.jsが行う。

まず全体図

基本戦略

  • とりあえずCloudFrontに各種ハンドリング周りを集約
    • WAF
    • S3 origin
    • API origin
  • WAF, S3 originそれぞれ弾いたときに403を返却するのを活用し、403返却時にNuxtのレンダリングに任せるようにerror pagesを設定
  • アプリケーションのソースコードは分割範囲を必要最低限にし、レポジトリのまま本番環境の適切なところに設置するだけとする。

大まかな図解

/api/*

/nova*

それ以外

403

403ページのレンダリング

1. WAF

WAF

  • ルールを指定してファイアーウォールをつけられる
    • IP制限、地理制限、ヘッダー制限, XSS, ファイルサイズ, SQLインジェクション, URIパスマッチ
  • 弾いたら403を返却する
  • 403のときのデザインは最悪なので、WAFだけ設置するはあんまり良くない

2. S3 Origin

S3 origin

  • ストレージ
  • nuxt generateをしたあとのファイルを置いておく
  • S3のオリジンを設定すると、CloudFrontで配信ができるようになる。
  • 存在しないファイルを読みに行こうとすると、404ではなく403が返却される
    • 理由は、404だと"存在しない"という情報をユーザに与えてしまうため、攻撃時の判断軸になってしまうからとのこと
    • バケットポリシーで弾いた場合と単純に存在しないものをユーザに分けて表示しないようにする意図があるらしい

3. CloudFront

CloudFront

  • CDN
  • エッジキャッシュだけではなく、WAFの設置やSSL証明書の配置、キャッシュしない設定にすることによるapiサーバーへのルーティングが可能
  • behaviorの設定によって、細かいルールが設定できる
  • S3に関してもWAFに関しても403を返却するため、Error Pagesでは403が来たら200を返却し/index.html(nuxtのデフォルトルーティング)を返すようにする
  • Nuxt側では、ルーティングが存在すればそれを表示し、そんざいしなければ404ページをレンダリングするようにするだけでOK

4. EC2

EC2

  • Laravelが乗っかってるインスタンス
  • ここに普通にNovaも同居
  • Novaへのアクセスは前述のWAFにてファイアーウォールを設置しているので、アクセスコントロールは特に行わない

フロント

api

管理画面

フロント

FW内

FW外

404

管理画面をいい感じに隠せる

この構成で

良かったこと

この構成で良かったこと

  • Laravel + Nuxtで管理画面を作ってしまうと、S3オリジンの返却する403とWAFが返却する403が競合し、正しくルーティングができなくなってしまう。
  • そこをLaravelNovaを使うと、Vue.jsレイヤーもインスタンス側のルーティングに持っていくことができるようになり、S3オリジンではなくEC2のオリジンを使えるようになり、WAFが競合せずに処理できるようになった。
  • CloudFrontを使ってS3のオリジンを見るようにしているため、SSR化したいとなったとしてもここのオリジンだけ切り替えれば良くなる。

まとめ

  • 当初は工数削減のためにLaravel Novaを使用したが、WAF周りのハンドリングがいい感じにできるようになったため、うまいことピースがハマった感じになった。
  • インフラ、サーバー、フロントをそれぞれ知見持った状態で技術選定すると、最適解が見えやすくなる

SCOUTERではエンジニアを募集しております!

http://bit.ly/scouter-laravel

http://bit.ly/scouter-vue

Made with Slides.com