Upgrade to Pro — share decks privately, control downloads, hide ads and more …

PHPでXOAUTH2を使ってGmailからメールを取り込む / Getting Mail from Gmail with XOAUTH2 in PHP

PHPでXOAUTH2を使ってGmailからメールを取り込む / Getting Mail from Gmail with XOAUTH2 in PHP

PHP勉強会@東京 #158の資料です。

資料中のリンクは以下です:
https://forest.watch.impress.co.jp/docs/news/1536442.html

HASEGAWA Tomoki

November 29, 2023
Tweet

More Decks by HASEGAWA Tomoki

Other Decks in Technology

Transcript

  1. 長谷川智希
    𝕏
    @tomzoh
    2023/11/27 PHP勉強会@東京 #158
    メールの仕組みと取り扱いへの入口
    PHPでXOAUTH2を使って
    Gmailからメールを取り込む

    View full-size slide

  2. 2
    ௕୩઒ஐر
    ͸͕ͤΘ ͱ΋͖
    @tomzoh
    http://www.dgcircus.com
    デジタルサーカス株式会社 副団長CTO
    ॴଐ ٕज़ΧϯϑΝϨϯεओ࠻
    دߘɾஶॻ
    来たれ!PHPer!We are hiring!
    𝕏

    View full-size slide

  3. 3
    ௕୩઒ஐر
    ͸͕ͤΘ ͱ΋͖
    @tomzoh
    ςοΫΧϯϑΝϨϯεӡӦࢀՃ 8FCJ04ΞϓϦ։ൃ
    $16 ϨτϩήʔϜػ ిࢠ޻࡞
    Ϗʔϧ αοΧʔ؍ઓ ϨϯλϧΧʔτϨʔε ʜ
    ϥΠϑϫʔΫ
    𝕏

    View full-size slide

  4. 長谷川智希 @tomzoh
    PHPでXOAUTH2を使ってGmailからメールを取り込む 4
    メールの仕組みと取り扱いへの入口
    PHPでXOAUTH2を使って
    Gmailからメールを取り込む

    View full-size slide

  5. 長谷川智希 @tomzoh
    PHPでXOAUTH2を使ってGmailからメールを取り込む
    今日のテーマ
    テーマ1 そもそもメールって何?
    SMTP?POP3?IMAP?
    テーマ2 PHPでメールを取り込む
    テーマ3 最近のGmail対応
    5

    View full-size slide

  6. 長谷川智希 @tomzoh
    PHPでXOAUTH2を使ってGmailからメールを取り込む
    そもそもメールって何?
    6

    View full-size slide

  7. 長谷川智希 @tomzoh
    PHPでXOAUTH2を使ってGmailからメールを取り込む
    メール
    • インターネット最古のアプリケーション
    • インターネット前身のJUNET
    • ホスト間をUUCPによるバケツリレー方式で転送
    • この頃からISO-2022-JPだったらしい
    • インターネットニュースとともに利用されていた
    • 現在のメール
    • メールサーバ間でSMTPによるバケツリレー方式で転送
    • 文字エンコーディングはさすがにUTF-8かな…
    (が、ISO-2022-JPに対応しなくて良い訳ではない)
    7

    View full-size slide

  8. 長谷川智希 @tomzoh
    PHPでXOAUTH2を使ってGmailからメールを取り込む
    メール転送方式
    SMTP, POP3, IMAP4
    8
    101*.
    "1
    4.
    51
    4.51 4.51
    4.51αʔό 4.51αʔό
    101*."1αʔό
    ϝʔϧΞϓϦ͸4.51αʔό
    ʹ4.51ͰϝʔϧΛૹ৴͢Δ
    4.51αʔό͸ࣗ਎ͷઃఆʹ
    ैͬͯϝʔϧΛసૹ͢Δ
    ϝʔϧΞϓϦ͸
    ϝʔϧαʔό͔Β
    ϝʔϧΛऔΓࠐΉ
    4.51αʔό

    View full-size slide

  9. 長谷川智希 @tomzoh
    PHPでXOAUTH2を使ってGmailからメールを取り込む
    POP3とIMAP4
    • どちらもメールサーバに届いたメールを読むためのプロトコル
    • 基本思想が違う
    • POP3 サーバからメールを取り込む思想
    • メールを取り込んでメールサーバからは削除する
    • メールの管理はローカルでする
    • IMAP4 サーバ上にメールを置いたまま運用する思想
    • サーバに届いたメールを閲覧する
    • メールの管理はサーバでする
    • フォルダを作ったりメールを移動したりもできる
    9

    View full-size slide

  10. 長谷川智希 @tomzoh
    PHPでXOAUTH2を使ってGmailからメールを取り込む
    メール転送方式
    SMTP, POP3, IMAP4
    10
    101*.
    "1
    4.
    51
    4.51 4.51
    4.51αʔό 4.51αʔό
    101*."1αʔό
    ϝʔϧΞϓϦ͸4.51αʔό
    ʹ4.51ͰϝʔϧΛૹ৴͢Δ
    4.51αʔό͸ࣗ਎ͷઃఆʹ
    ैͬͯϝʔϧΛసૹ͢Δ
    ϝʔϧΞϓϦ͸
    ϝʔϧαʔό͔Β
    ϝʔϧΛऔΓࠐΉ
    4.51αʔό

    View full-size slide

  11. 長谷川智希 @tomzoh
    PHPでXOAUTH2を使ってGmailからメールを取り込む
    メールアプリなんて使ってませんけど…?
    • Gmailをお使いの方など
    • GmailはWeb UIのメールアプリを持っている
    • SMTPサーバ, POP3サーバ, IMAP4サーバも持っている
    • 外部からPOP3やIMAP4でGmailに届いたメールを取り込むこともできる
    • Gmail(サービス) =
    SMTPサーバ + POP3サーバ + IMAP4サーバ + Web UI
    11

    View full-size slide

  12. 長谷川智希 @tomzoh
    PHPでXOAUTH2を使ってGmailからメールを取り込む
    PHPでメールを取り込む
    12

    View full-size slide

  13. 長谷川智希 @tomzoh
    PHPでXOAUTH2を使ってGmailからメールを取り込む
    101*.
    "1
    4.51αʔό 4.51αʔό
    101*."1αʔό
    4.
    51
    4.51 4.51
    4.51αʔό
    メールを取り込む
    13
    メールを取り込むには
    コレをやれば良い
    = POP3かIMAP4を喋る

    View full-size slide

  14. 長谷川智希 @tomzoh
    PHPでXOAUTH2を使ってGmailからメールを取り込む
    PHPでPOP3/IMAP4を喋る
    • Packagistで探す
    上位のやつはどれでもちゃんと使える
    と思われる
    • forteeでは以下を使っています
    POP3 tedivm/fetch
    IMAP4 webklex/php-imap
    14
    長谷川智希 @tomzoh
    PHPでXOAUTH2を使ってGmailからメールを取り込む

    View full-size slide

  15. 長谷川智希 @tomzoh
    PHPでXOAUTH2を使ってGmailからメールを取り込む
    POP3 or IMAP4
    PHPから取り込む時にどちらを使うと良いか
    • POP3 メールが到着順に並んでいる
    • すべて取り込みたいのであればシンプル
    • 取り込み済かの判断は日時やMessage-IDから自力でやる
    • IMAP4 メールがフォルダに格納されている
    • クライアント側でサーバのメールをリアルタイムにそのまま表示するのであればシンプル
    • サーバ上のすべてのメールを取り込みたい場合はフォルダの走査が必要
    • つまり…
    • 複数メールサーバからメールを取り込んで1つのリストに表示する場合はPOP3がシンプル
    • 単独のメールサーバのメールを表示したいだけならIMAP4がシンプル
    15

    View full-size slide

  16. 長谷川智希 @tomzoh
    PHPでXOAUTH2を使ってGmailからメールを取り込む
    メールの闇
    • メールはインターネット最古のアプリケーション
    • さまざまなメールアプリ(送信)がある
    • それぞれのメールアプリ(送信)が自己解釈で好き勝手にメールを送る
    • メールアプリ(受信)は自由奔放なメールを良い感じにパースする必要がある
    • どえらいHTMLでも解釈できるWebブラウザみたいなもの
    • …をPHP(に限らずプログラム)で処理するのはたいへんつらい
    • text/plainって書いてあるのにHTMLだったり
    • ISO-2022-JPって書いてあるのにUTF-8だったり
    • メールライブラリを自分で書こうとするのは修羅の道かも…
    16

    View full-size slide

  17. 長谷川智希 @tomzoh
    PHPでXOAUTH2を使ってGmailからメールを取り込む
    最近のGmail対応
    17

    View full-size slide

  18. 長谷川智希 @tomzoh
    PHPでXOAUTH2を使ってGmailからメールを取り込む
    GmailのPOP3/IMAP仕様
    • Gmail(サービス) =
    SMTPサーバ + POP3サーバ + IMAP4サーバ + Web UI
    • GmailからはPOP3やIMAP4でメールを取り込める
    • POP3/IMAP4にはID/パスワードが必要
    • 太古のGmailはアカウントのID/パスワードでPOP3/IMAP4接続できた
    • 今はアプリパスワードを作成して、アカウントのID/アプリパスワードで接続できる
    • 将来的にアプリパスワードは廃止され *1 、XOAUTH2を使う必要がありそう
    18
    *1 https://forest.watch.impress.co.jp/docs/news/1536442.html
    この記事のリンク先を良く見るとアプリパスワードは残る様にも見える…。

    View full-size slide

  19. 長谷川智希 @tomzoh
    PHPでXOAUTH2を使ってGmailからメールを取り込む
    XOAUTH2
    • oAuthみたいにWebのリダイレクトを経由してトークンを得るメカニズム
    • 手順はoAuthと同じ oAuth用のライブラリ(League\OAuth2)が使えた
    • IDとトークンでPOP3/IMAP4接続する
    • 単純にPOP3/IMAP4のパスワードの代わりにトークンを使用する訳ではない
    • = XOAUTH2に対応したライブラリが必要
    19
    C: AUTH PLAIN
    S: +
    C: dGVzdAB0ZXN0AHRlc3Q=
    S: +OK Maildrop locked and ready
    1-"*/
    C: AUTH XOAUTH2
    S: +
    C: dXNlcj1zb21ldXNlckBleGFtcGxl...Q2cBAQ==
    S: +OK User successfully authenticated.
    90"65)

    View full-size slide

  20. 長谷川智希 @tomzoh
    PHPでXOAUTH2を使ってGmailからメールを取り込む
    PHP + XOAUTH2 on fortee
    • forteeではPOP3を使っている
    • Gmail + XOAUTH2でもPOP3を使いたかった
    • tedivm/fetch はXOAUTH2に対応していなかった
    • このライブラリは日本語環境で使う時に困る仕様/バグがちょいちょいある
    • forteeではいくつかパッチを当てて使っている
    • と言うかXOAUTH2に対応したライブラリはあまり無い
    • webklex/php-imap が対応していたので採用した
    • IMAP4になってしまった
    20

    View full-size slide

  21. 長谷川智希 @tomzoh
    PHPでXOAUTH2を使ってGmailからメールを取り込む
    GmailからIMAP4でメールを取り込む
    forteeでの実装例
    • Gmailではメールが来るとINBOXフォルダに格納される
    • 他のクライアント(GmailのWeb UIとか)で移動されない前提でINBOXからだけ取り込むことにした
    • INBOXという名前はIMAP4の仕様ではなくGmailの仕様
    • IMAP4の仕様:
    • メールはUIDを持っている
    • UIDの範囲を指定してメールを検索できる
    • フォルダの情報を取得すると次に採番されるUIDがわかる
    • UIDによる取り込み状態管理
    • 前回取り込んだ時のUID最大値とINBOXで次に採番されるUIDの範囲で取得する
    • webklex/php-imap が範囲指定をサポートしていなかったのでパッチを当てて使っている
    21

    View full-size slide

  22. 長谷川智希 @tomzoh
    PHPでXOAUTH2を使ってGmailからメールを取り込む
    IMAP4を使った場合のPros/Cons
    • Pros: 高速
    • UID指定でメールを取得できるので必要なメールだけ取得できる
    • 日付指定でメールを取得できるので初回取り込み時にも高速
    • Pros: パース済のメールを操作できる(気がする)
    • 操作するメールがIMAP4サーバでパース済なのでひどいメールを操作しなくて済む(気がする)
    • 気のせいかもしれない or/and Gmailだけかもしれない
    • 少なくともクライアントは"添付メール部分だけ"みたいな形でリクエストできる
    • Cons: IMAP4サーバ独自仕様に巻きこまれる
    • IMAP4の仕様外の挙動はサービスに合わせる必要がある (受信メールが入るフォルダなど)
    22

    View full-size slide

  23. 長谷川智希 @tomzoh
    PHPでXOAUTH2を使ってGmailからメールを取り込む
    まとめ
    23

    View full-size slide

  24. 長谷川智希 @tomzoh
    PHPでXOAUTH2を使ってGmailからメールを取り込む
    まとめ
    • メール = インターネット太古のアプリケーション
    • メールはSMTPで転送されPOP3/IMAP4で取り込む
    • PHPでPOP3/IMAP4を喋るライブラリは複数ある
    • POP3/IMAP4のどちらを使うかはアプリのユースケースから考えよう
    • Gmailからメールを取り込むにはXOAUTH2対応が必要そう
    • うまく使うとIMAP4は便利
    24
    長谷川 智希
    @tomzoh
    𝕏

    View full-size slide