Yahoo JAPAN さんがFirebase Authenticationを使ってFlutter製アプリにYahoo! JAPAN IDでログインしてみるという記事を書いてくださっているので、この記事通りに進めるとFirebase Authenticationであっさり実装できますが、Flutter webであったり、Desktop に流用したいのでSDKは使わないでWebViewを介した認証方式を実装してみました。
Yahoo! ID 連携 v2 を使用して実装します。認証の流れはHybridフローを採用しましたOAuthの説明は書かないのでわからない方は調べてみてください。
認証の流れは
となります。
実装
1.ユーザー認証リクエストをして、初期ページのURLを取得する
初期ページ表示のためのURLを取得します。
apiKey callbackUri はYahoo!デベロッパーネットワークに記載されています。
Map<String, String> params = {
'response_type': 'code token',
'client_id': apiKey,
'redirect_uri': callbackUri,
'scope': 'openid profile email',
'nonce': dtNow.toString(),
};
String requestParams = '';
params.forEach((String k, String v) {
if (requestParams == '') {
requestParams += '$k=';
} else {
requestParams += '&$k=';
}
if (k == 'response_type' || k == 'redirect_uri' || k == 'scope') {
requestParams += Uri.encodeComponent(v);
} else {
requestParams += v;
}
});
2.WebViewで初期ページを表示する
今回はwebview_flutterを使用します
他にflutter_webview_pluginやflutter_inappbrowserもあります。
好きなプラグインで実装してください。
1で取得したURLでユーザー認証・同意画面が表示されます。
return Scaffold(
appBar: AppBar(title: Text('Yahoo! アカウント連携')),
body: WebView(
initialUrl: 初期ページのURL,
javascriptMode: JavascriptMode.unrestricted,
navigationDelegate: (NavigationRequest request) async {
/// URLの遷移をハンドリングできます
if (request.url.startWith(callbackUrl)) {
final accessToken = request.url.split('#').last;
await login(accessToken);
}
return NavigationDecision.navigate;
}
),
);
3.アクセストークンを取得する
ユーザーが同意したら Yahoo!側から Access Token、ID Token、Authorization Code が返ってきます。この続きの処理はサーバーサイドの処理に合わせて、いい感じに処理してください。
サーバーサイドの実装の代わりにFirebase Authenticationを使うこともできます。
Future<void> login(String tokens) async {
Map<String, String> params = {};
tokens.split('&').forEach((String param) {
params[param.split('=').first] = param.split('=').last;
});
/// 認証サーバの処理に合わせて必要な情報を送信する処理を書く
}
後日サーバーサイドの処理の記事も書きます。