※iOS 12 で SFAuthenticationSession
は Deprecated になりました。今後は ASWebAuthenticationSession
を使いましょう!
https://developer.apple.com/documentation/authenticationservices/aswebauthenticationsession
以下の記事にある SFAuthenticationSession
は ASWebAuthenticationSession
に適宜読み替えてください。
下記の @glayash さんによる記事でも書かれていますが、iOS 10 までは Safari と SFSafariViewController の認証情報が共有されていました。
iOS 11 / Android O 時代のアプリ認証 - Qiita
しかし、iOS 11 からはそれぞれ独立した Cookie ストレージを持つように仕様が変更されました。
そこで iOS 11 beta 3 からは Safari の認証情報を共有できる SFAuthenticationSession というクラスが登場するのですが、この記事ではその使い方を説明したいと思います。
実行環境
- Xcode 9.2
準備
今回は foursquare にログインしてみます。予め Foursquare 開発者サイト からアプリを新規登録し、CLIENT_ID と Redirect URI を取得しておきます。Redirect URI には fsoauthexample://authorized
を設定してください。
実装手順
Xcode を起動し、適当なサンプルプロジェクトを作ります。
プロジェクト名は何でもいいです。
URL Schemes の設定
2017.8.8 追記:SFAuthenticationSession
初期化時に引数でスキームを指定する場合、この設定は不要です
fsoauthexample://
でアプリが立ち上がるように設定しておきます。
実装
SafariServices をインポートします。
import SafariServices
引数 url
に認証用のURLを指定して、SFAuthenticationSession を呼び出します。
let url = URL(string: "https://ja.foursquare.com/oauth2/authenticate?client_id=
(YOUR_CLIENT_ID)&response_type=token&redirect_uri=fsoauthexample://authorized")!
self.session = SFAuthenticationSession(url: url, callbackURLScheme: nil) { url, error in
print(url)
// fsoauthexample://authorized#access_token=XXXXXXXXXXXXXX
}
session?.start()
※Xcode 9 beta 3 の時点では引数 callbackURLScheme
に何を指定しても挙動が変わりませんでした(詳しい方いましたら教えてください)。
2017.8.8 追記:Xcode 9 beta 5になって、ようやく挙動に変化が現れました。callbackURLScheme
にスキームを指定しておけば Info.plist への指定が不要になります。
start()
メソッドを実行すると「アプリがSafariの情報を使うけど問題ない?」的なアラートが表示された後、 SFSafariViewController のような画面(本記事では「ログイン画面」と呼ぶことにします)がモーダル表示されます。
すでに Safari で Foursquare にログイン済みの場合は即座に redirect url(fsoauthexample://authorized)にリダイレクトがかかり、そのタイミングで completionHandler
が実行されます。
未ログインの場合は、IDとパスワードを入力する通常のログイン画面が表示されます。ログインが成功すると、redirect url にリダイレクトがかかり、そのタイミングで completionHandler
が実行されます。
completionHandler
の url
にはリダイレクト先の URL がセットされているので、ここから access_token を取り出すことができます。
fsoauthexample://authorized#access_token=XXXXXXXXXXXXXX
completionHandler
が実行されるタイミングでログイン画面は自動的に閉じますが、cancel()
メソッドを呼ぶことにより、意図したタイミングでログイン画面を閉じることもできます。
これで SFAuthenticationSession
によるシングルサインオンが完了しました。
サンプルコード