6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

TORICOAdvent Calendar 2019

Day 6

Flutter で Yahoo! JAPAN ID のログインを実装する

Last updated at Posted at 2019-12-05

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_pluginflutter_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;
  });
  
  /// 認証サーバの処理に合わせて必要な情報を送信する処理を書く
}

後日サーバーサイドの処理の記事も書きます。

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?