前提・実現したいこと
表題の件について
デモ用に用意されていた認証サイトにログインし、自分のアプリに戻ってくるコードをかきましたが下記の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
どうぞよろしくお願いいたします。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。