Laravel PassportでOAuthサーバーを実装、クライアントアプリでAPIアクセスを確認

OAuthサーバーをLaravel Passportで実装する手順について解説します。

仕事では、Laravelでサービスを運用しているわけではないですが、クラウド プラットフォームのOAuthクライアント機能を調べたりするときにOAuthサーバーがわでデバッグしたいときなどに、Laravel Passportは簡単に実装してサーバーを立てられるのでとても便利に使っています。

以下、Laravelプロジェクトを新規に作るところから、PassportでOAuthサーバーを実装し、クライアントアプリからPassportサーバーに認可コードフローでアクセストークンを取得し、それを使ってAPIからユーザ情報を取得するまで、実装して確認してみます。

Laravel Passportとは

Laravel Passportは、Laravelプロジェクト公式のOAuthサーバー実装です。
OAuthサーバーというとざっくりですが、APIへのアクセス認可とアクセストークンを発行を管理するサーバーのことという理解で良いかと思います。

Laravel Passport provides a full OAuth2 server implementation for your Laravel application in a matter of minutes. Passport is built on top of the League OAuth2 server that is maintained by Andy Millington and Simon Hamp.

ドキュメントに記載されていますが、SPAやモバイルアプリの認証とトークン発行への用途の場合は、Laravel Sanctumの仕様を推奨されています。
“Laravel PassportでOAuthサーバーを実装、クライアントアプリでAPIアクセスを確認” の続きを読む

LaravelプロジェクトをHerokuにデプロイする手順

LaravelプロジェクトをHerokuにデプロイする手順です。
データベースは、Heroku Postgresアドインを追加して設定します。

Qiitaなどに同様の記事はたくさんあがっていますが、改めて見返すと結構よくまとまっているので公開することにしました。

前提条件

  • composer
  • Heroku CLI

Heroku CLIのセットアップ

Heroku CLIはHomebrewでインストール可能です。

以下のコマンドでインストール
“LaravelプロジェクトをHerokuにデプロイする手順” の続きを読む

FullCalendar 4をlaravel/mixでビルドして利用する

LaravelのプロジェクトでFullCalendarを導入する方法についてまとめてみました。

FullCalendarを利用するにはscriptタグでソースを読み込む方法もありますが、メンテナンス性を考えるとパッケージをnpmで管理して、Laravel Mixを利用してビルドするのが良い方法です。

特にFullCalendar 4からはコア以外の機能はプラグインの形で都度追加する必要があるためよりパッケージ管理システムを利用することが推奨されています。

Laravel Mixとは

以前の記事、Laravel 6.x laravel/uiを利用してbootstrap 4を適用する で少し触れていますが、Laravel Mixは、Laravelのフロントエンド ビルド環境で、Webpackを簡単に利用するラッパーみたいなものです。

Laravel Mixのセットアップは以下のようにプロジェクトの作成後npm installするだけで、自らWebpack環境を用意しなくてもLaravelと組み合わせてVue.jsやReactを簡単に使い始められます。

$ composer create-project --prefer-dist laravel/laravel laravel-fullcalendar
$ cd laravel-fullcalendar
$ npm install

ビルドの設定はwebpack.mix.jsファイルに記述します。例えば、jsとcssのビルドする場合、以下のように入力ファイルと出力するディレクトリを指定するだけです。

mix.js('resources/js/app.js', 'public/js')
    .sass('resources/sass/app.scss', 'public/css');

とても簡単ですね。

ビルドはnpm run dev、開発中はnpm run watchしてすぐ開発が進められます。

また、通常Webpackで複数の入力ファイルを扱うのは工夫が必要ですが、Laravel Mixなら以下のように簡単に追加できます。

mix.js('resources/js/blog.js', 'public/js')
    .sass('resources/sass/blog.scss', 'public/css');
mix.js('resources/js/admin.js', 'public/js')
    .sass('resources/sass/admin.scss', 'public/css');

例えば、これはブログ記事と管理画面のビューで使うjsやcssのアセットをビルドするイメージです。

FullCalendarのインストール

ここから本題ですが、まずFullCalendarのパッケージをnpmで追加していきます。

この記事では、FullCalendarのビューはTimeGrid Viewのみを使用します。
また、予定をドラッグで変更できるようにするのと、複数のタイムゾーンに対応したいので、interactionmoment-timezoneも追加します。
まとめるとコアも含めFullCalendar関連は以下の4つのパッケージをインストールします。

  • @fullcalendar/core
  • @fullcalendar/timegrid
  • @fullcalendar/interaction
  • @fullcalendar/moment-timezone

また、@fullcalendar/moment-timezoneは、moment-timezoneを別途インストールする必要があります。

以下のコマンドでインストールします。

$ npm install @fullcalendar/core @fullcalendar/timegrid @fullcalendar/interaction moment-timezone @fullcalendar/moment-timezone

FullCalendarの実装

resources/js/app.jsを編集しても良いですが、FullCalendarはすべてのページで使用することは無いと思うので、js、cssファイルを分けます。

resources/js/fullcalendar.jsを追加して以下を記述します

// resources/js/fullcalendar.js
import { Calendar } from '@fullcalendar/core'
import timeGridPlugin from '@fullcalendar/timegrid';
import interactionPlugin from '@fullcalendar/interaction';
import momentTimezonePlugin from '@fullcalendar/moment-timezone';

document.addEventListener('DOMContentLoaded', function () {
  const calendarEl = document.getElementById('calendar');

  const calendar = new Calendar(calendarEl, {
    allDaySlot: false,
    plugins: [timeGridPlugin, momentTimezonePlugin, interactionPlugin],
    timeZone: 'Asia/Tokyo', // momentTimezonePlugin
    defaultView: 'timeGridWeek',

    events: []
  });

  calendar.render();
});

次に、スタイルシートresources/css/fullcalendar.scssを追加して以下を記述します。

// resources/css/fullcalendar.scss
@import "~@fullcalendar/core/main.css";
@import "~@fullcalendar/timegrid/main.css";

Laravel Mixの設定ファイルに上記のファイルを読み込む設定を追加します。

// webpack.mix.js

mix.js('resources/js/fullcalendar.js', 'public/js')
  .sass('resources/sass/fullcalendar.scss', 'public/css');

ここでビルドしてみましょう。

$ npm run dev

以下のように、ビルドされたresources/js/fullcalendar.jspublic/js/fullcalendar.jsに、resources/css/fullcalendar.scsspublic/css/fullcalendar.cssに出力されます。

Laravel Mixでjs、cssをビルド

生成したアセットをビューで読み込んで表示してみます。

とりあえずここではwelcome.blade.phpを以下のように置き換えてみます。

// resources/views/welcome.blade.php

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Laravel</title>

        <link href="{{ asset('css/fullcalendar.css') }}" rel="stylesheet">
        <script src="{{ asset('js/fullcalendar.js') }}" defer></script>
    </head>
    <body>
        <div id="calendar"></div>
    </body>
</html>

開発サーバーを起動してhttp://127.0.0.1:8000を開きます。

$ php artisan serve

予定を表示したり追加したりできませんが、FullCalendarの表示ができました。

FullCalendarをLaravelのビューに表示

Laravel Homestead内のPostgreSQLにMacのpsqlから接続する手順

少し前に開発機のMacを買い替えたためHomesteadの環境を作り直してみました。
LaravelプロジェクトのデータベースにはPostgreSQLを使っているのですが、改めて環境を作るにあたってPostgreSQLをメインの仕事で使うことは無いし、psqlでHomesteadのPostgreSQLに接続するためだけにMacのローカルにPostgreSQLサーバーをインストールしたくないと思い、psqlだけ使えるようにする方法について調べてみました。

イマイチ一次情報にた取り付けずなところも多かったのですが、執筆時点でおそらくベストっぽい構成のような気がします。

psqlのインストール

homebrewでpsqlをインストールします。

homebrewには「psql」という名前のパッケージ(Formula)は無いですが、libpqをインストールするとpsqlが含まれています。

$ brew install libpq
...
<!--more-->

==> libpq
libpq is keg-only, which means it was not symlinked into /usr/local,
because conflicts with postgres formula.

If you need to have libpq first in your PATH run:
  echo 'export PATH="/usr/local/opt/libpq/bin:$PATH"' >> /Users/hrendoh/.bash_profile

For compilers to find libpq you may need to set:
  export LDFLAGS="-L/usr/local/opt/libpq/lib"
  export CPPFLAGS="-I/usr/local/opt/libpq/include"


$ brew link --force libpq
Linking /usr/local/Cellar/libpq/12.3... 370 symlinks created

If you need to have this software first in your PATH instead consider running:
  echo 'export PATH="/usr/local/opt/libpq/bin:$PATH"' >> /Users/hrendoh/.bash_profile

インストール時に出力されるメッセージで「libqdはkeg-onlyなので、/usr/localにシンボリックリンクは作成されませんよ」と言われています。

ところで「keg-only」とは、一般用語に直すと、homebrewのパッケージが配置されるディレクトリ(Celler)へライブラリなど(Keg)をダウンロードして配置するだけのパッケージ(Fomula)ということらしいです。

Homebrew用語、よく知らないで使っていたので調べてしまいまいした。

参照

話を戻すと、libqpをインストールしてもパスが通っていないので、以下のどちらかの手順を実行してパスを通します。

  1. brew linkコマンドで/usr/local/binにシンボリックリンクを作成する
$ brew link --force libpq
  1. .bash_profileなどでパスを通す
echo 'export PATH="/usr/local/opt/libpq/bin:$PATH"' >> /Users/$(whoami)/.bash_profile

以上で、psqlが使えるようになります。

では実際に接続してみます。

Homesteadは、PostgreSQLのポートは54320でフォワードされてますので以下のようにポートを指定して接続します。

$ psql -U homestead -h localhost -p 54320
Password for user homestead: 
psql (12.3, server 12.2 (Ubuntu 12.2-2.pgdg18.04+1))
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.

homestead=# 

無事接続できました。しかし、Laravelで開発しててpsqlでアクセスするのってcreate databaseするときくらいのような。。

参照: Ports | Laravel Homestead – Laravel – The PHP Framework For Web Artisans

補足

Error: The following directories are not writable by your userを解決するには

$ brew install libpq 
Error: The following directories are not writable by your user:
/usr/local/lib/pkgconfig

You should change the ownership of these directories to your user.
  sudo chown -R $(whoami) /usr/local/lib/pkgconfig

And make sure that your user has write permission.
  chmod u+w /usr/local/lib/pkgconfig

メッセージの説明に従い、自分に対して/usr/local/lib/pkgconfigに書き込み権限を付けます

$ sudo chown -R $(whoami) /usr/local/lib/pkgconfig
$ chmod u+w /usr/local/lib/pkgconfig

Laravel 6.x laravel/uiを利用してbootstrap 4を適用する

Laravel2 Advent Calendar 2019 – Qiita の15日目の記事になります。
(ちょうど空いていたのでぎりぎりですが参加させていただきました。)

Laravel 5.8以前ではフロントエンド フレームワークとしてbootstrapとVueがはじめから利用可能なように設定されていましたが、Laravel 6.xではデフォルトでは含まれなくなりました。

6.xでBootstrapを利用するには、フロントエンドのScafolding機能を提供するlaravel/uiのコマンドを使用してJavascriptのビルドとCSSのプリプロセッサ設定を生成する必要があります。

この記事では、Laravel 6.xのプロジェクトにlaravel/uiを利用してBootstrapをプロジェクトに導入する手順についてシンプルなアプリケーションを例に解説しています。
想定しているケースは、主にサーバー側のビューテンプレートで画面を実装する場合に、アプリケーション全体でBootstrap 4の基本的な機能を使ってマークアップと多少画面の動きをつけたい(DatePickerを利用したいなど)といった構成のアプリケーションです。
本格的にフロントエンド開発の環境を整えるには、Laravel Mixについても学ぶ必要がありますが、デフォルトのwebpack.mix.jsの設定でできる範囲にとどめて深堀りしません。

この記事のサンプルソースは Github リポジトリ https://github.com/hrendoh/laravel-ui-bootstrap-tasks に公開しています。記事の中で解説していないソースコードについてはこちらを参照ください。
“Laravel 6.x laravel/uiを利用してbootstrap 4を適用する” の続きを読む

LaravelのセッションをHeroku Redisに保存する

LaravelアプリのセッションをHeroku Redisに保存する設定する手順についてまとめてみます。

HerokuでRedisを利用する場合、現在(2019.11)は公式のHeroku Redisを利用できます。

公式ドキュメントはこちら: Heroku Redis | Heroku Dev Center

セッションをキャッシュに入れるのはなぜか?

ところで、改めてHerokuでセッションをRedisなどのストレージに保存する必要があるのか?ってことなんですが、試しにfree Dynoを使っていてすぐにDynoがsleepしてしまうような場合は、DynoのファイルシステムはEphemeral Disk(揮発性ディスク)なのでRedisなどに保存しておかないとsleepするたびにセッションが切れてしまいます。
また、Hobby以上のDynoの場合でも1日一回は再起動されるとのことなのでやはりキャッシュストレージに入れておいた方が良さそうです。
参照: Restarting | Dynos and the Dyno Manager

一方、1日1回くらいならまあいいかとしてDynoが複数の場合はでは必要なのか?って話ですが、セッション固定機能のSession Affinityを使えば問題ないかもしれません。
“LaravelのセッションをHeroku Redisに保存する” の続きを読む

HerokuにデプロイしたLaravelアプリのアセットのURLをhttpsにする手順

HerokuではSSLの処理をロードバランサーで行っているので、Dyno上のLaravelアプリケーションはデフォルト設定ではhttpで動いていると判定されアセットのURLがhttpになってしまします。

そのまま表示すると以下のようにブラウザの警告が出てしまいます。

Herokuのロードバランサーまわりについては、公式ドキュメントのHTTP Routingで説明されています。

Laravelで、ロードバランサー経由のhttpsリクエストを判定するには、公式ドキュメント「HTTP Requests」の「Configuring Trusted Proxies」の「Trusting All Proxies」に記述されている通りApp\Http\Middlewar\TrustProxiesクラスのproxiesの値にロードバランサーのIPアドレスをセットします。
Herokuの場合、そもそもロードバランサーのIPアドレスは判らないのですし、Web DynoにはグローバルIPアドレスは割あたってない(はず)ので、すべてのプロキシからのリクエストを信頼する「*」をセットします。

“HerokuにデプロイしたLaravelアプリのアセットのURLをhttpsにする手順” の続きを読む

Laravel 6.x on Heroku mailgun アドオンでメール送信実装手順

Laravel 6.xでは、3rdパーティのメール送信サービスMailgun, Postmark, Amazon SESが標準で選択できます。バージョンによっては、MandrillやSparkPostもサポートしていたようです。Transportのクラスは残っているので設定すれば使えるかもしれません。

一方、この記事を書いている2019年10月時点でHerokuアドオンとして利用可能なメールサービス(SMS含む)のラインナップは以下の通りです。

よって、Laravel 標準サポートで、Herokuのアドオンとして利用可能なサービスはMailgunのみとなります。
“Laravel 6.x on Heroku mailgun アドオンでメール送信実装手順” の続きを読む

Laravel 6.x でCSV出力を実装する(レスポンスストリームにそのまま返す版)

LaravelでCSV出力を実装してみたので手順をまとめます。

動作確認はLaravel 6でしていますが、この記事の内容は5.6以降で利用可能です。

CSVのサイズが大きくなる場合は、コントローラはCSV生成タスクをバックグラウンドキューに入れて非同期ジョブでCSVを生成してS3などのストレージに追加、処理が完了したらファイルのURLを応答に含めて通知するというのが正しい実装な気がしますが、ここではCSVに含めるレコードが少なくファイルサイズが小さめな限定的なケースを想定し、CSVを生成しながらそのまま応答ストリームに流すような実装について解説します。

小さめと書きましたが、プロセスのメモリーを節約して実行するのでネットワーク環境と多重度が低くプロセスを長めに専有することを許容できるシステムであれば大量レコードでも使えるのでプロジェクトによっては大量レコードのダウンロードにも使える仕組みとなっています。

利用するLaravelフレームワークの機能を整理

まずサンプル実装に使うLaravelの機能について解説してみます。

ストリームを応答として返す

大容量のファイルをストリームで帰す場合は、streamDownloadメソッドを利用します。streamDownloadメソッドは、Laravel 5.6から導入されたメソッドです。

Laravelのドキュメント HTTP ResponsesのFile Downloads Streamed Downloads で説明されています。
“Laravel 6.x でCSV出力を実装する(レスポンスストリームにそのまま返す版)” の続きを読む

Heroku SchedulerでLaravelのartisanコマンドを実行する

LaravelのartisanコマンドをHeroku Schedulerを使って、定期実行する手順に確認したのでまとめてみました。

Laravelのバージョンは、2019年9月時点での最新6.0で確認しています。

Heroku Schedulerのとは

Heroku Schedulerは、cronジョブ的な仕組みを提供するHeroku公式アドオンです。

ドキュメントによると実行間隔は10分、1時間、1日のみです。
この要件で問題なければ非常に便利な機能です。

実行時刻は正確ではないので、ジョブを正確な時刻に実行する必要がある場合はここで説明するSchedulerではなくCustom Clock Processを利用する必要があります。

また、Heroku Schedulerジョブで実行するタスクの実行時間について「Long-running jobs」には、実行時間が数分を超えるような長いタスクを実行する場合は、バックグラウンドキューに入れてワーカーDynoでタスクを実行するべきと書いてあります。
更に、スケジューラーで起動されたDynoは、次のスケジュール実行時間になると停止するとも書いてあります。
よって、基本的にはLaravelの場合QueuesをワーカーDynoで起動しておいて、スケジュールジョブではジョブをディスパッチするのみにするのが正しい実装になります。

しかし、この記事では、まずはHeroku Schedulerの動作の雰囲気を掴むため、Heroku Schedulerのジョブからシンプルなartisan commandを直接実行して動作を確認してみます。
“Heroku SchedulerでLaravelのartisanコマンドを実行する” の続きを読む