質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

OAuth

OAuth(Open Authorization)は、APIを通して保護されたリソース(サードパーティのアプリケーション)へアクセスする為のオープンプロトコルです。

OAuth 2.0

OAuth 2.0(Open Authorization 2.0)は、APIを通して保護されたリソース(サードパーティのアプリケーション)へアクセスする為のオープンプロトコルです。

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

Q&A

1回答

2765閲覧

flutterでflutter_appauthプラグインを使ってoauthログインを実装したい2

sagme

総合スコア10

Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

OAuth

OAuth(Open Authorization)は、APIを通して保護されたリソース(サードパーティのアプリケーション)へアクセスする為のオープンプロトコルです。

OAuth 2.0

OAuth 2.0(Open Authorization 2.0)は、APIを通して保護されたリソース(サードパーティのアプリケーション)へアクセスする為のオープンプロトコルです。

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

1グッド

0クリップ

投稿2020/03/31 14:06

編集2020/04/01 04:51

前提・実現したいこと

表題の件について
デモ用に用意されていた認証サイトにログインし、自分のアプリに戻ってくるコードをかきましたが下記の2点で困っています。
1. アプリの画面遷移の動作が意図と違っているので変えたい
2. デモ用の認証サイトではなく別の認証サイトに実装を変更したいが、分からない。

下記リンクflutter_appauth 0.8.1のページのExampleと
flutter_appauth 0.8.1

GitHubのコードを参照して実装しました。
MaikuB/flutter_appauth

認証サイトとログインページはこちらです。
デモサイト
ログインページ

●現状のアプリの動作

アプリ起動時に表示される初期画面の「ログインページへ」ボタンを押すと、ログインページにリダイレクトして
そこであらかじめ用意されているユーザアカウントでログインすると
認証済みとなり、自分のアプリに戻ってきます。

① アプリ初期画面
イメージ説明
② リダイレクト画面
イメージ説明
③ リダイレクト画面にユーザID,PWを入力 bob/bob
イメージ説明
④ 認証成功
イメージ説明
⑤ 自動で自分のアプリの初期画面に戻る(ここが意図と違う動き)
イメージ説明
⑥ screen1に画面遷移(取得したAPIの内容を表示)
イメージ説明

発生している問題・エラーメッセージ

困っていること 1. について
画面遷移①〜⑥の流れで、認証成功したら前の初期画面に自動で戻ってしまう(⑤の動き)のを
④認証成功したら⑥screen1に直接遷移したいのですが
どうやったら遷移先が変更できるのかが分かりません。

困っていること 2. について
プラグインを使って認証する時に、3つのURLを指定するのですが
認証サイトを変更した場合は、何を指定したら良いのかが分かりません。

指定するのは下記の実装部分の、_redirectUrlに1つと_serviceConfigurationに2つ指定するURLの合計3つです
特に_redirectUrlは、デモサイトのURL(demo.identityserver.io)の逆さまにしたもの(io.identityserver.demo)
プラス :/oauthredirect という文字列になっていますが
これは、サイトが変わっても、認証サーバのURLを逆さまにしたもの + :/oauthredirect を
指定すれば良いのでしょうか?
そもそもなぜ逆さまにするのか、実際にリダイレクトされるログインページのURLと異なる文字列を指定して
ちゃんと遷移するのは何故なんでしょうか?

final AuthorizationTokenResponse result = await _appAuth.authorizeAndExchangeCode( AuthorizationTokenRequest( _clientId, // 'native.code' _redirectUrl, // 'io.identityserver.demo:/oauthredirect' serviceConfiguration: _serviceConfiguration,  // 'https://demo.identityserver.io/connect/authorize', // 'https://demo.identityserver.io/connect/token'; scopes: _scopes), );

該当のソースコード

dart

1main.dart 2 3import 'package:flutter/material.dart'; 4import 'package:http/http.dart' as http; 5import 'package:flutter_appauth/flutter_appauth.dart'; 6import 'package:flutter_auth_login_app/screen1.dart'; 7 8void main() => runApp(MyApp()); 9 10class MyApp extends StatelessWidget { 11 12 13 Widget build(BuildContext context) { 14 return MaterialApp( 15 title: 'Flutter Demo', 16 theme: ThemeData( 17 18 primarySwatch: Colors.blue, 19 ), 20 home: MyHomePage(title: 'Flutter Demo Home Page'), 21 ); 22 } 23} 24 25class MyHomePage extends StatefulWidget { 26 MyHomePage({Key key, this.title}) : super(key: key); 27 28 final String title; 29 30 31 _MyHomePageState createState() => _MyHomePageState(); 32} 33 34class _MyHomePageState extends State<MyHomePage> { 35 36 final String _clientId = 'native.code'; 37 final String _redirectUrl = 'io.identityserver.demo:/oauthredirect'; 38// final String _discoveryUrl = 'https://demo.identityserver.io/.well-known/openid-configuration'; 39 40 final List<String> _scopes = <String>[ 41 'openid', 42 'profile', 43 'email', 44 'offline_access', 45 'api' 46 ]; 47 48 String _accessToken; 49 String _refreshToken; 50 String _userInfo = ''; 51 52 final FlutterAppAuth _appAuth = FlutterAppAuth(); 53 final TextEditingController _idTokenTextController = TextEditingController(); 54 final TextEditingController _accessTokenExpirationTextController = TextEditingController(); 55 final TextEditingController _accessTokenTextController = TextEditingController(); 56 final TextEditingController _refreshTokenTextController = TextEditingController(); 57 58 final AuthorizationServiceConfiguration _serviceConfiguration = 59 AuthorizationServiceConfiguration( 60 'https://demo.identityserver.io/connect/authorize', 61 'https://demo.identityserver.io/connect/token' 62 ); 63 64 65 void initState() { 66 super.initState(); 67 68 } 69 70 void _loginFunc() async { 71 // 認証コード無しでアクセス、ID、リフレッシュトークンを取ってくる場合 72 // show that we can also explicitly specify the endpoints rather than getting from the details from the discovery document 73 // 発見ドキュメントの詳細から取得するのではなく、エンドポイントを明示的に指定することもできることを示します 74 final AuthorizationTokenResponse result = 75 await _appAuth.authorizeAndExchangeCode( 76 AuthorizationTokenRequest( 77 _clientId, 78 _redirectUrl, 79 serviceConfiguration: _serviceConfiguration, // 'https://demo.identityserver.io/connect/authorize', 80 // 'https://demo.identityserver.io/connect/token'); 81 scopes: _scopes), 82 ); 83 84 // アクセス、ID、リフレッシュトークン格納 85 if (result != null) { 86 _accessToken = _accessTokenTextController.text = result.accessToken; 87 _idTokenTextController.text = result.idToken; 88 _refreshToken = _refreshTokenTextController.text = result.refreshToken; 89 _accessTokenExpirationTextController.text = result.accessTokenExpirationDateTime?.toIso8601String(); 90 } 91 92 // API取得 93 print('1=$result'); 94 if (result != null) { 95 print('1'); 96 await _testApi(result); // API取ってくる 97 } 98 // 画面遷移 99 _gotoScreen1(); 100 } 101 102 103 // API取得 104 Future<void> _testApi(TokenResponse response) async { 105 print('token=$_accessToken'); 106 final http.Response httpResponse = await http.get( 107 'https://demo.identityserver.io/api/test', 108 headers: <String, String>{'Authorization': 'Bearer $_accessToken'}); 109 setState(() { 110 _userInfo = httpResponse.statusCode == 200 ? httpResponse.body : ''; 111 // _isBusy = false; 112 }); 113 print('_userInfo=$_userInfo'); 114 } 115 116 // 画面遷移 screen1 初期画面に戻らない 117 void _gotoScreen1() { 118 // Navigator.push( 119 Navigator.pushReplacement( 120 context, 121 new MaterialPageRoute<Null>( 122 settings: const RouteSettings(name: "/screen1"), 123 builder: (BuildContext context) => Screen1(api:_userInfo), 124 ), 125 ); 126 } 127 128 // widget 129 130 Widget build(BuildContext context) { 131 132 return Scaffold( 133 appBar: AppBar(title: Text(widget.title),), 134 body: Center( 135 136 child: Column( 137 mainAxisAlignment: MainAxisAlignment.center, 138 children: <Widget>[ 139 140 Padding( 141 padding: EdgeInsets.only(bottom: 40), 142 child: Text('アプリ初期画面'), 143 ), 144 145 FlatButton(key:null, onPressed: _loginFunc, // _gotoScreen1 _loginFunc 146 shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(3.0)), 147 color: Color(0xFF4c6cb3), // 群青色 148 child: Text('ログインページへ',), 149 ) 150 ], 151 ), 152 ), 153 154 ); 155 } 156}

dart

1screen1.dart 2 3import 'package:flutter/material.dart'; 4import 'package:http/http.dart' as http; 5import 'package:flutter_appauth/flutter_appauth.dart'; 6 7//// widget //// 8class Screen1 extends StatefulWidget { 9 String api; 10 11 Screen1({Key key, this.api}): super(key: key); 12 13 14 _Screen1State createState() => _Screen1State(this.api); 15} 16 17class _Screen1State extends State<Screen1> { 18 String _api; 19 20 _Screen1State(String api){ 21 this._api = api; 22 } 23 24 25 void initState() { 26 super.initState(); 27 28 } 29 30 31 Widget build(BuildContext context) { 32 33 return Scaffold( 34 resizeToAvoidBottomInset: false, 35 appBar: AppBar(title: Text('screen1'),), 36 body: Column( 37 children: [ 38 Text('screen1'), 39 Text('$_api'), 40 ] 41 ) 42 ); 43 } 44}

試したこと

同じプラグインを使用した実装例がないか探してみましたが
探し出せませんでした。
特に_redirectUrlの部分をどうしたらいいか分からず、別の実装を試すことが出来ない状態です。

補足情報(FW/ツールのバージョンなど)

macOS Mojave
Flutter 1.12.13+hotfix.5
Tools • Dart 2.7.0

どうぞよろしくお願いいたします。

KenTsuchiya👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

追記:
解決はしていないのですが、色々試したところ現象が変化し
困っている内容が変わったため、こちらの質問を一旦クローズし、新たに質問を立て直させて頂きます。

○現在の状況
困っていること 1. について
認証成功した後に一旦前の画面に戻ってしまう動作については、とりあえず保留にしておきます。
(遷移先を変更できるなら尚良しというスタンス)

困っていること 2. について
_redirectUrlに自前で用意した認証サーバで指定しているredirect URLを指定し、_serviceConfigurationに指定する2つのURLは、それぞれ用意した
認証エンドポイントとトークンエンドポイントのURLを指定したところ
自前の認証サーバのログイン画面を表示し、認証してリダイレクトするところまでは進みました。ただ
callback先からアプリに戻ってこないため、そこで困っています。

追記:
_redirectUrlに指定するURLについて、カスタムスキーム + :/oauthredirect を指定すると
リダイレクト先として、認証後に元のアプリに戻るようです。

カスタムスキームを使用する設定として、 android/app/build.gradle と、 ios/Runner/info.plist に
同じカスタムスキームを設定しておくことと
認証サーバ側でリダイレクトを許可するURLの指定に カスタムスキーム + :/oauthredirect を
設定することが必要です。



別に質問を立てましたが、上記の質問も解決方法ご存知の方がいれば、引き続きご意見をお待ちしています。

内容を修正した次の質問を立てましたので、よろしければそちらもご参照お願いします。
flutterでflutter_appauthプラグインを使ってoauthログインを実装したい3

投稿2020/04/07 04:03

編集2020/04/14 06:09
sagme

総合スコア10

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問