用 Require-Recipient-Valid-Since (RRVS) 解決帳號失效的問題

在「Facebook Yahoo Require-Recipient-Valid-Since SMTP Extension」這篇看到 Require-Recipient-Valid-Since (RRVS) 變成 Proposed Standard 了:「The Require-Recipient-Valid-Since Header Field and SMTP Service Extension」(RFC 7293)。

起因是從 2013 年的「yourname@yahoo.com Can Be Yours!」這篇開始的:Yahoo! 宣佈會釋出太久沒有使用的 @yahoo.com 帳號讓其他人可以註冊。

而這導致了帳號綁定問題:如果使用者先前在 Facebook 上 (或是其他服務) 有綁定 Yahoo! 帳號,而他的 Yahoo! 帳號被釋出被其他人拿走後,其他人就可以利用重設密碼的功能取得 Facebook 帳號權限。

Yahoo! 對這個問題的解法是透過 Require-Recipient-Valid-Since 處理,服務方 (像是 Facebook) 在發出重要信件時帶入 Require-Recipient-Valid-Since,要求這封信必須在某個時間點後有效,才能讓收信者看到這封信的內容。

Facebook 的人在「Protecting Facebook Accounts With New Email Standard」也提到了這個新標準。

關於 PHP 的 require 與 include (以及 *_once)

本來以為寫過了,後來找了找沒找到...

星期五的時候跟 Gasol 聊了一下,後來查資料後整理出來。(主要是 include 的文件說明)

requireinclude 的差異在於找不到檔案時,include 會產生 warning,而 require 會產生 fatal error:

The include construct will emit a warning if it cannot find a file; this is different behavior from require, which will emit a fatal error.

而對 include_path 的處理則是「遇到有指定 path 時就忽略 include_path」,而對 require './foo.php' 的解讀是「relative to the current directory」:

If a path is defined — whether absolute (starting with a drive letter or \ on Windows, or / on Unix/Linux systems) or relative to the current directory (starting with . or ..) — the include_path will be ignored altogether. For example, if a filename begins with ../, the parser will look in the parent directory to find the requested file.

由於不是「檔案所在的路徑」而是「current directory」,會受到 chdir() 的影響。一般在程式碼內的基準應該是「這個 script 所在的路徑」,而非「current directory」,所以寫法應該是:

<?php
require __DIR__ . PATH_SEPARATOR . 'foo.php';

<?php
# 直接假設在 Mac OS X & Linux & FreeBSD 上跑...
require __DIR__ . '/foo.php';

而這種寫法就得依靠 include_path 內有 .,而且還要祈禱不會在其他的目錄裡出現同樣檔名:

<?php
require 'foo.php';