iOS和macOS上的Message-ID和Mail.app深度鏈接

来源:https://www.cnblogs.com/Mayday9527/archive/2019/11/09/11825558.html
-Advertisement-
Play Games

如何在iOS上通過電子郵件進行無縫的“無密碼”身份驗證。 Apple平臺上的郵件和日曆集成 在macOS和iOS上查看電子郵件時,郵件會在[檢測到的日期和時間]下劃線 。您可以與他們互動以創建新的日曆事件。如果您在“日曆”中打開此類活動,則會在其擴展詳細信息中看到“在郵件中顯示”鏈接。單擊此鏈接可將 ...


如何在iOS上通過電子郵件進行無縫的“無密碼”身份驗證。

Apple平臺上的郵件和日曆集成

在macOS和iOS上查看電子郵件時,郵件會在[檢測到的日期和時間]下劃線 。您可以與他們互動以創建新的日曆事件。如果您在“日曆”中打開此類活動,則會在其擴展詳細信息中看到“在郵件中顯示”鏈接。單擊此鏈接可將您帶回到原始電子郵件。此功能可以追溯到iPhone的發佈。它將被納入當年的 [Mac OS X版本(Leopard)中,] 這將標志著許多移動功能中的第一個進入台式機。

如果要將“魔術” URL複製到粘貼板併在文本編輯器中查看,則會看到以下內容:

"message:%3C1572873882024.NSHIPSTER%40mail.example.com%3E"

經驗豐富的iOS開發人員將立即意識到使用 [自定義URL方案]。其中精通網路的用戶可以對主機進行百分比解碼,並識別出它類似於電子郵件地址,但事實並非如此。

因此,如果沒有電子郵件地址,我們在這裡看什麼?
這是另一個不同的電子郵件欄位,稱為Message-ID

另外,如果你想一起進階,不妨添加一下交流群[1012951431],選擇加入一起交流,一起學習。期待你的加入!(進群可領取學習禮包)

消息ID

[RFC 5322§3.6.4]規定,每封電子郵件應該 具有“消息ID:”欄位包含單個唯一消息標識符。該標識符的語法本質上是一個帶有尖括弧(< >)的電子郵件地址。

儘管該規範未包含任何有關生成良好Message-ID的規範性指導,但 1998年的[IETF草案草稿]還是很不錯的。

讓我們看一下如何在Swift中執行此操作:

生成隨機消息ID

前述文檔中描述的第一種技術涉及生成帶有64位隨機數的隨機消息ID,該消息ID帶有時間戳,以進一步減少衝突的機會。我們可以使用Swift 5內置的隨機數生成器API和[String(_:radix:uppercase:)初始化]程式來輕鬆完成此操作 :

import Foundation

let timestamp = String(Int(Date().timeIntervalSince1970 * 1000))
let nonce = String(UInt64.random(in: 0..<UInt64.max), radix: 36, uppercase: true)
let domain = "mail.example.com"

let MessageID = "<\(timestamp).\(nonce)@\(domain)>"
//"<[email protected]>"

然後,我們可以將生成的Message-ID與關聯的記錄一起保存,以便以後鏈接到它。但是,在許多情況下,一種更簡單的選擇是使消息ID具有確定性,並且可以從其現有狀態進行計算。

生成確定性消息ID

考慮符合[Identifiable協議]且其關聯`ID`類型為 [UUID]的記錄結構 。您可以這樣生成消息ID:

import Foundation

func messageID<Value>(for value: Value, domain: String) -> String
where Value: Identifiable, Value.ID == UUID
{
return "<\(value.id.uuidString)@\(domain)>"
}

如果缺少持久性標識符(或任何其他區別功能),則可以改用消息正文本身的摘要來生成消息ID。這是使用新的[CryptoKit框架]的示例實現 :

import Foundation
import CryptoKit

let body = #"""
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat.
"""#

let digest = Data(SHA256.hash(data: body.data(using: .utf8)!))
.map { String($0, radix: 16, uppercase: true) }
.joined()

let domain = "ADF"
"<\(digest)@\(domain)>"
// "<F52380112175FCE8ECF2731C193EB8A7CC8642E53C68D292CD88531D42F145@mail.example.com>"

 移動深層鏈接

iOS和macOS上的常規Mail客戶端都將嘗試`message:`通過啟動到前臺並嘗試使用編碼的Message-ID欄位打開消息來使用自定義方案打開URL 。

生成具有消息ID的郵件深層鏈接

掌握了Message-ID之後,最後的任務是創建一個深層鏈接,您可以使用該深層鏈接將Mail打開到關聯的消息。唯一的技巧是 在URL中對消息ID 進行 [百分比編碼]。您可以使用[方法]來執行此操作 ,但是我們更願意將所有操作委托給-這具有進一步的優勢,即無需使用[格式字元串]就可以完整構建URL 。[`adding PercentEncoding(withAllowedCharacters:)`][`URLComponents`]

import Foundation

var components = URLComponents()
components.scheme = "message"
components.host = MessageID
components.string!
// "message://%3C1572873882024.NSHIPSTER%40mail.example.com%3E"

據我們所知,自定義`message:`方案後是否存在雙斜杠不會對郵件深層鏈接解析產生任何影響。

打開郵件深層鏈接

如果您`message:`在iOS上打開URL,並且可以從 其中一個帳戶的inbox輕鬆訪問鏈接的消息,則Mail將立即啟動該消息。如果找不到該消息,則該應用程式將啟動併在後臺非同步載入該消息,併在可用時將其打開。相比之下,嘗試在macOS上打開到尚未載入的郵件的郵件深層鏈接會導致顯示警報模式。因此,我們建議僅在iOS上使用郵件深層鏈接。例如, [飛行學校]使用無密碼身份驗證系統來執行此操作。要訪問書籍的電子副本,請輸入用於購買書籍的電子郵件地址。提交表單後,iOS上的用戶將看到一個深層鏈接,用於打開指向包含“魔術登錄鏈接”✨的電子郵件的Mail應用程式。

其他系統可能使用消息ID通過[通用鏈接]簡化其本機應用或網站的無密碼身份驗證 ,或者將其合併為2fa策略的一部分 (因為[出於此目的,不再認為][sms是安全的])。如果您在Web應用程式中使用Rails,則 [ActiveMailer攔截器]提供了一種方便的方式來Message-ID為無密碼驗證流註入欄位。


與蘋果平臺上如此眾多的私人集成(仍然是第一方應用程式的專有領域)不同,“在郵件中顯示”的秘密之處在於我們所有人都能參與進來。儘管沒有記錄,但是由於該功能與系統的深度集成以及植根於基本Web標準中,因此該功能不太可能很快被刪除。

從[瀏覽器供應商], [社交媒體公司]到 [政府](甚至有時甚至是蘋果[公司)的]每個人都 試圖拆開開放的網路並控制我們可以看到和執行的操作時,很高興得知電子郵件 [將近50年了],保持互聯網自由和分散的能力仍然堅決。

翻譯地址: https://nshipster.com/message-id/

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 之前,在Codeproject發表過一篇關於用現有表中數據創建Insert的Sql語句的存儲過程,今天將其搬到這裡來,註意本存儲過程僅適用於SQL SERVER。 介紹 一些時候,你想導出一些現有表中記錄的Sql腳本以便你可以插入這些數據到另一個資料庫的相似表中。有很多方式可以做到,現在,我將跟大家 ...
  • create function f_split(@c varchar(2000),@split varchar(2)) returns @t table(col varchar(20)) as begin while(charindex(@split,@c)<>0) begin insert @t( ...
  • 檢測是不是數字型的數據, 兩種方法 1. ISNUMERIC ( expression ) 2. PATINDEX ( ‘%pattern%‘ , expression ) 1. ISNUMERIC ( expression ) 如果是數字類型則返回 1 ,不是則返回 0 但ISNUMERIC有時是 ...
  • 在網上有關Redis相關文章滿天飛的時候,這個時候我決定重溫一下NoSQL。它是什麼,用於解決什麼問題,有哪些相類似的技術,與傳統的關係型資料庫有哪些差別,什麼時候使用?也正如書中所說的,篇幅短小,內容卻很豐富。新技術的誕生,我們應該以既穩健又前瞻的心態看待它。 1. 它是什麼,用於解決什麼問題? ...
  • select *,stuff(select ‘,’ + fieldname from table1 for xml path(”)),1,1,”) as field from table2 for xml path(”) ,自從 SQL Server2005及更高版本提供了一個新查詢語法 ,主要是用 ...
  • 上圖為MySQL的簡易架構圖,給您有一個大概的概念,下麵我將為您進行進一步的分析。 連接器: 當連接MySQL資料庫時,等待的將是MySQL服務端的連接器;連接器的職責是和客戶端建立連接、獲取許可權、維持和管理連接。客戶端連接命令一般是如下所示(建議:不要在命令中顯示添加登入密碼): mysql -h ...
  • SQLServer有四個主要組件:協議,關係引擎(也稱為查詢處理器)、存儲引擎和SQLOS。來自任何客戶端的應用程式,只要是交給SQL Server執行,都必須與這四個組件交互。 協議組件:用於接收請求,並把它們轉換成關係引擎可以處理的形式。另外,協議層還獲取所有查詢的最終結果、狀態消息或錯誤消息, ...
  • 一、介紹 在iOS開發中,轉場動畫的使用無處不見,不只是我們自己更多的使用UIViewblock動畫實現一個轉場動畫,其實,在我們實現VC控制器跳轉的時候都是轉場動畫的實現,例如標簽欄控制器的切換、模態動畫present和dismiss、導航控制器的push和pop。實現它們的轉場動畫,只需要實現它 ...
一周排行
    -Advertisement-
    Play Games
  • Dapr Outbox 是1.12中的功能。 本文只介紹Dapr Outbox 執行流程,Dapr Outbox基本用法請閱讀官方文檔 。本文中appID=order-processor,topic=orders 本文前提知識:熟悉Dapr狀態管理、Dapr發佈訂閱和Outbox 模式。 Outbo ...
  • 引言 在前幾章我們深度講解了單元測試和集成測試的基礎知識,這一章我們來講解一下代碼覆蓋率,代碼覆蓋率是單元測試運行的度量值,覆蓋率通常以百分比表示,用於衡量代碼被測試覆蓋的程度,幫助開發人員評估測試用例的質量和代碼的健壯性。常見的覆蓋率包括語句覆蓋率(Line Coverage)、分支覆蓋率(Bra ...
  • 前言 本文介紹瞭如何使用S7.NET庫實現對西門子PLC DB塊數據的讀寫,記錄了使用電腦模擬,模擬PLC,自至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1.Windows環境下鏈路層網路訪問的行業標準工具(WinPcap_4_1_3.exe)下載鏈接:http ...
  • 從依賴倒置原則(Dependency Inversion Principle, DIP)到控制反轉(Inversion of Control, IoC)再到依賴註入(Dependency Injection, DI)的演進過程,我們可以理解為一種逐步抽象和解耦的設計思想。這種思想在C#等面向對象的編 ...
  • 關於Python中的私有屬性和私有方法 Python對於類的成員沒有嚴格的訪問控制限制,這與其他面相對對象語言有區別。關於私有屬性和私有方法,有如下要點: 1、通常我們約定,兩個下劃線開頭的屬性是私有的(private)。其他為公共的(public); 2、類內部可以訪問私有屬性(方法); 3、類外 ...
  • C++ 訪問說明符 訪問說明符是 C++ 中控制類成員(屬性和方法)可訪問性的關鍵字。它們用於封裝類數據並保護其免受意外修改或濫用。 三種訪問說明符: public:允許從類外部的任何地方訪問成員。 private:僅允許在類內部訪問成員。 protected:允許在類內部及其派生類中訪問成員。 示 ...
  • 寫這個隨筆說一下C++的static_cast和dynamic_cast用在子類與父類的指針轉換時的一些事宜。首先,【static_cast,dynamic_cast】【父類指針,子類指針】,兩兩一組,共有4種組合:用 static_cast 父類轉子類、用 static_cast 子類轉父類、使用 ...
  • /******************************************************************************************************** * * * 設計雙向鏈表的介面 * * * * Copyright (c) 2023-2 ...
  • 相信接觸過spring做開發的小伙伴們一定使用過@ComponentScan註解 @ComponentScan("com.wangm.lifecycle") public class AppConfig { } @ComponentScan指定basePackage,將包下的類按照一定規則註冊成Be ...
  • 操作系統 :CentOS 7.6_x64 opensips版本: 2.4.9 python版本:2.7.5 python作為腳本語言,使用起來很方便,查了下opensips的文檔,支持使用python腳本寫邏輯代碼。今天整理下CentOS7環境下opensips2.4.9的python模塊筆記及使用 ...