LaravelでDropboxを扱おうとしたら思いの外苦戦したので、これから同じようなことをしている人の苦労を減らすために、調べてわかったことをまとめます。
やり方だけがわかればいいやという人は、laravel-dropbox-with-short-lived-access-token/README_ja.md at main · Asano-Naoki/laravel-dropbox-with-short-lived-access-tokenをご覧ください。
1.従来のやり方
LaravelもDropboxもメジャーなサービスであり、LaravelでDropboxを操作するのも楽勝だろうと安易に考えていました。Laravelの公式ドキュメントのFile Storage – Laravel – The PHP Framework For Web Artisansにも記載があるくらいですから。この公式ドキュメントや、簡単!LaravelでDropboxにアップロード&ダウンロード – console dot logなどを参考にすれば、比較的簡単にできると思いました。
従来はきっとこのやり方で簡単にできたのでしょう。しかし2022年5月に挑戦した私は、あえなく跳ね返されました。
2.権限の設定
アクセストークンを生成して設定しても、なぜかファイルがアップロードされずに苦しみました。エラーも表示されなかったので原因もわかりませんでした。
いろいろいじってみると、dropboxで作成したappのpermissionsタブでfiles.content.writeのボックスをチェックしてからアクセストークンを生成すればファイルのアップロードができることに気づきました。アクセストークンを生成してからボックスをチェックしてもダメでした。順序が重要だということに気づきづらかったです。
3.アクセストークンの失効
これでもうdropboxへのファイルアップロードができると思い込み、バックアップコマンドに組み込みました。しかしなぜかバックアップファイルがdropboxにアップロードされていませんでした。手動でコマンドを実行すると、エラーメッセージからアクセストークンが失効しているということがわかりました。
適当なワードで検索し、Solved: API access token expired – Dropbox Communityにたどり着きました。そこからSolved: Re: Tokens only valid for 4 hours from app console – Dropbox Communityへとリンクをたどりました。そこで公式が回答していることを読み、Access token expirationドロップダウンメニューを何度も探しましたが、私が作成したdropbox appにはどうしても見つかりません。今新しく作成したdropbox appにはその表示はないようです。
filesystems – Upload to Dropbox not working from Laravel with Dropbox driver – Stack Overflowやspatie/dropbox-api: A minimal implementation of Dropbox API v2を読む限り、app keyとapp secretの指定で動作しそうに思えましたが、自分で実験するとその方法ではダメでした。
dcblogdev/laravel-dropbox: A Laravel package for working with Dropbox API v2.を使えばできそうではありましたが、設定箇所が多く、データベースやrouteもいじるのかと抵抗を覚え、もっと原理的でシンプルなやり方でできないものかと模索しました。
Dropbox OAuth Guide – Dropboxなどを読み、リフレッシュトークンからその都度短期アクセストークンを生成すればよいのではないかと考えました。同じ方向で考えているLambdaでDropboxのアクセストークンを取得する – Qiitaを参考にしました。
試行錯誤の末に、app key, app secret、リフレッシュトークンからその都度短期アクセストークンを生成することに成功しました。
4.結論
LaravelからDropboxを操作するという需要は多くありそうですから、最新のdropboxの仕組みでも実現できる方法をここに共有します。