Flutter
...
Authentication
FlutterでParseユーザーセッションの現在ユーザーを取得
12 分
セッション中の現在のユーザーを取得する はじめに ユーザーがアプリを開くたびにログインしなければならないのは楽しくありません。これを回避するために、キャッシュされた現在のparseuserオブジェクトを使用できます。サインアップまたはログインメソッドを使用するたびに、ユーザーはローカルにキャッシュされます。このキャッシュをセッションとして管理し、ユーザーが自動的にログインしていると仮定できます。 このガイドでは、あなたのflutterアプリのためにparseuserクラスを使用して、セッション中の現在のユーザーを取得するための flutterプラグイン for parse server の使い方を学びます。 目標 flutterアプリのためにparseを使用して、セッション中の現在のユーザーを取得します。 前提条件 このチュートリアルを完了するには、次のものが必要です: flutter バージョン 2 2 x 以降 https //flutter dev/docs/get started/install android studio https //developer android com/studio または vs code をインストール ( プラグイン dart と flutter を使用) back4app に接続された flutter アプリ。 注意: flutter プロジェクトに parse sdk をインストール を参照して、back4app に接続された flutter プロジェクトを作成してください。 前のガイドを完了して、 parseuser parseuser クラスをよりよく理解してください。 android または ios を実行しているデバイス(シミュレーターではない)。 現在のユーザーアプリの理解 現在のユーザーのセッションプロセスをよりよく理解するために、ユーザーのサインアップ、ログイン、ログアウトを行うアプリを作成します。このアプリケーションは、サインアップ、ログイン、ログアウトを行う前のガイドに似ています。次のガイドでも同じプロジェクトを使用するため、まだ利用できない機能がいくつかあります。 このガイドの主な焦点は、flutter と parse を使用することなので、flutter アプリケーションのコードについては説明しません。次の手順に従って、back4app データベースでログインおよびログアウトアプリを構築します。 さあ、始めましょう! 次の手順では、現在のユーザーを取得するアプリを構築できるようになります。 1 ログイン/ログアウトアプリテンプレートを作成する 前のガイドからflutterプロジェクトを開きます parse server用のflutterプラグイン 。main dartファイルに移動し、すべてのコードをクリーンアップして、次の内容に置き換えます 1 import 'package\ flutter/material dart'; 2 import 'package\ parse server sdk flutter/parse server sdk dart'; 3 4 void main() async { 5 widgetsflutterbinding ensureinitialized(); 6 7 final keyapplicationid = 'your app id here'; 8 final keyclientkey = 'your client key here'; 9 final keyparseserverurl = 'https //parseapi back4app com'; 10 11 await parse() initialize(keyapplicationid, keyparseserverurl, 12 clientkey keyclientkey, 13 debug true); 14 15 runapp(myapp()); 16 } 17 18 class myapp extends statelesswidget { 19 future\<bool> hasuserlogged() async { 20 return future value(false); 21 } 22 23 @override 24 widget build(buildcontext context) { 25 return materialapp( 26 title 'flutter parse server', 27 theme themedata( 28 primaryswatch colors blue, 29 visualdensity visualdensity adaptiveplatformdensity, 30 ), 31 home futurebuilder\<bool>( 32 future hasuserlogged(), 33 builder (context, snapshot) { 34 switch (snapshot connectionstate) { 35 case connectionstate none 36 case connectionstate waiting 37 return scaffold( 38 body center( 39 child container( 40 width 100, 41 height 100, 42 child circularprogressindicator()), 43 ), 44 ); 45 default 46 if (snapshot hasdata && snapshot data!) { 47 return userpage(); 48 } else { 49 return loginpage(); 50 } 51 } 52 }), 53 ); 54 } 55 } 56 57 class loginpage extends statefulwidget { 58 @override 59 loginpagestate createstate() => loginpagestate(); 60 } 61 62 class loginpagestate extends state\<loginpage> { 63 final controllerusername = texteditingcontroller(); 64 final controllerpassword = texteditingcontroller(); 65 bool isloggedin = false; 66 67 @override 68 widget build(buildcontext context) { 69 return scaffold( 70 appbar appbar( 71 title const text('flutter parse server'), 72 ), 73 body center( 74 child singlechildscrollview( 75 padding const edgeinsets all(8), 76 child column( 77 crossaxisalignment crossaxisalignment stretch, 78 children \[ 79 container( 80 height 200, 81 child image network( 82 'https //blog back4app com/wp content/uploads/2017/11/logo b4a 1 768x175 1 png'), 83 ), 84 center( 85 child const text('flutter on back4app', 86 style 87 textstyle(fontsize 18, fontweight fontweight bold)), 88 ), 89 sizedbox( 90 height 16, 91 ), 92 textfield( 93 controller controllerusername, 94 enabled !isloggedin, 95 keyboardtype textinputtype text, 96 textcapitalization textcapitalization none, 97 autocorrect false, 98 decoration inputdecoration( 99 border outlineinputborder( 100 borderside borderside(color colors black)), 101 labeltext 'username'), 102 ), 103 sizedbox( 104 height 8, 105 ), 106 textfield( 107 controller controllerpassword, 108 enabled !isloggedin, 109 obscuretext true, 110 keyboardtype textinputtype text, 111 textcapitalization textcapitalization none, 112 autocorrect false, 113 decoration inputdecoration( 114 border outlineinputborder( 115 borderside borderside(color colors black)), 116 labeltext 'password'), 117 ), 118 sizedbox( 119 height 16, 120 ), 121 container( 122 height 50, 123 child elevatedbutton( 124 child const text('login'), 125 onpressed isloggedin ? null () => douserlogin(), 126 ), 127 ), 128 sizedbox( 129 height 16, 130 ), 131 container( 132 height 50, 133 child elevatedbutton( 134 child const text('sign up'), 135 onpressed () => navigatetosignup(), 136 ), 137 ), 138 sizedbox( 139 height 16, 140 ), 141 container( 142 height 50, 143 child elevatedbutton( 144 child const text('reset password'), 145 onpressed () => navigatetoresetpassword(), 146 ), 147 ) 148 ), 149 ), 150 ), 151 )); 152 } 153 154 void douserlogin() async { 155 final username = controllerusername text trim(); 156 final password = controllerpassword text trim(); 157 158 final user = parseuser(username, password, null); 159 160 var response = await user login(); 161 162 if (response success) { 163 navigatetouser(); 164 } else { 165 message showerror(context context, message response error! message); 166 } 167 } 168 169 void navigatetouser() { 170 navigator pushandremoveuntil( 171 context, 172 materialpageroute(builder (context) => userpage()), 173 (route\<dynamic> route) => false, 174 ); 175 } 176 177 void navigatetosignup() { 178 navigator push( 179 context, 180 materialpageroute(builder (context) => signuppage()), 181 ); 182 } 183 184 void navigatetoresetpassword() { 185 navigator push( 186 context, 187 materialpageroute(builder (context) => resetpasswordpage()), 188 ); 189 } 190 } 191 192 class signuppage extends statefulwidget { 193 @override 194 signuppagestate createstate() => signuppagestate(); 195 } 196 197 class signuppagestate extends state\<signuppage> { 198 final controllerusername = texteditingcontroller(); 199 final controllerpassword = texteditingcontroller(); 200 final controlleremail = texteditingcontroller(); 201 202 @override 203 widget build(buildcontext context) { 204 return scaffold( 205 appbar appbar( 206 title const text('flutter sign up'), 207 ), 208 body center( 209 child singlechildscrollview( 210 padding const edgeinsets all(8), 211 child column( 212 crossaxisalignment crossaxisalignment stretch, 213 children \[ 214 container( 215 height 200, 216 child image network( 217 'https //blog back4app com/wp content/uploads/2017/11/logo b4a 1 768x175 1 png'), 218 ), 219 center( 220 child const text('flutter on back4app', 221 style 222 textstyle(fontsize 18, fontweight fontweight bold)), 223 ), 224 sizedbox( 225 height 16, 226 ), 227 center( 228 child const text('user registration', 229 style textstyle(fontsize 16)), 230 ), 231 sizedbox( 232 height 16, 233 ), 234 textfield( 235 controller controllerusername, 236 keyboardtype textinputtype text, 237 textcapitalization textcapitalization none, 238 autocorrect false, 239 decoration inputdecoration( 240 border outlineinputborder( 241 borderside borderside(color colors black)), 242 labeltext 'username'), 243 ), 244 sizedbox( 245 height 8, 246 ), 247 textfield( 248 controller controlleremail, 249 keyboardtype textinputtype emailaddress, 250 textcapitalization textcapitalization none, 251 autocorrect false, 252 decoration inputdecoration( 253 border outlineinputborder( 254 borderside borderside(color colors black)), 255 labeltext 'e mail'), 256 ), 257 sizedbox( 258 height 8, 259 ), 260 textfield( 261 controller controllerpassword, 262 obscuretext true, 263 keyboardtype textinputtype text, 264 textcapitalization textcapitalization none, 265 autocorrect false, 266 decoration inputdecoration( 267 border outlineinputborder( 268 borderside borderside(color colors black)), 269 labeltext 'password'), 270 ), 271 sizedbox( 272 height 8, 273 ), 274 container( 275 height 50, 276 child elevatedbutton( 277 child const text('sign up'), 278 onpressed () => douserregistration(), 279 ), 280 ) 281 ], 282 ), 283 ), 284 )); 285 } 286 287 void douserregistration() async { 288 final username = controllerusername text trim(); 289 final email = controlleremail text trim(); 290 final password = controllerpassword text trim(); 291 292 final user = parseuser createuser(username, password, email); 293 294 var response = await user signup(); 295 296 if (response success) { 297 message showsuccess( 298 context context, 299 message 'user was successfully created!', 300 onpressed () async { 301 navigator pushandremoveuntil( 302 context, 303 materialpageroute(builder (context) => userpage()), 304 (route\<dynamic> route) => false, 305 ); 306 }); 307 } else { 308 message showerror(context context, message response error! message); 309 } 310 } 311 } 312 313 class userpage extends statelesswidget { 314 parseuser? currentuser; 315 316 future\<parseuser?> getuser() async { 317 } 318 319 @override 320 widget build(buildcontext context) { 321 void douserlogout() async { 322 var response = await currentuser! logout(); 323 if (response success) { 324 message showsuccess( 325 context context, 326 message 'user was successfully logout!', 327 onpressed () { 328 navigator pushandremoveuntil( 329 context, 330 materialpageroute(builder (context) => loginpage()), 331 (route\<dynamic> route) => false, 332 ); 333 }); 334 } else { 335 message showerror(context context, message response error! message); 336 } 337 } 338 339 return scaffold( 340 appbar appbar( 341 title text('user logged in current user'), 342 ), 343 body futurebuilder\<parseuser?>( 344 future getuser(), 345 builder (context, snapshot) { 346 switch (snapshot connectionstate) { 347 case connectionstate none 348 case connectionstate waiting 349 return center( 350 child container( 351 width 100, 352 height 100, 353 child circularprogressindicator()), 354 ); 355 default 356 return padding( 357 padding const edgeinsets all(8 0), 358 child column( 359 crossaxisalignment crossaxisalignment stretch, 360 mainaxisalignment mainaxisalignment center, 361 children \[ 362 center( 363 child text('hello, ${snapshot data! username}')), 364 sizedbox( 365 height 16, 366 ), 367 container( 368 height 50, 369 child elevatedbutton( 370 child const text('logout'), 371 onpressed () => douserlogout(), 372 ), 373 ), 374 ], 375 ), 376 ); 377 } 378 })); 379 } 380 } 381 382 class resetpasswordpage extends statefulwidget { 383 @override 384 resetpasswordpagestate createstate() => resetpasswordpagestate(); 385 } 386 387 class resetpasswordpagestate extends state\<resetpasswordpage> { 388 final controlleremail = texteditingcontroller(); 389 390 @override 391 widget build(buildcontext context) { 392 return scaffold( 393 appbar appbar( 394 title text('reset password'), 395 ), 396 body singlechildscrollview( 397 padding const edgeinsets all(8), 398 child column( 399 crossaxisalignment crossaxisalignment stretch, 400 children \[ 401 textfield( 402 controller controlleremail, 403 keyboardtype textinputtype emailaddress, 404 textcapitalization textcapitalization none, 405 autocorrect false, 406 decoration inputdecoration( 407 border outlineinputborder( 408 borderside borderside(color colors black)), 409 labeltext 'e mail'), 410 ), 411 sizedbox( 412 height 8, 413 ), 414 container( 415 height 50, 416 child elevatedbutton( 417 child const text('reset password'), 418 onpressed () => douserresetpassword(), 419 ), 420 ) 421 ], 422 ), 423 )); 424 } 425 426 void douserresetpassword() async {} 427 } 428 429 class message { 430 static void showsuccess( 431 {required buildcontext context, 432 required string message, 433 voidcallback? onpressed}) { 434 showdialog( 435 context context, 436 builder (buildcontext context) { 437 return alertdialog( 438 title const text("success!"), 439 content text(message), 440 actions \<widget>\[ 441 new elevatedbutton( 442 child const text("ok"), 443 onpressed () { 444 navigator of(context) pop(); 445 if (onpressed != null) { 446 onpressed(); 447 } 448 }, 449 ), 450 ], 451 ); 452 }, 453 ); 454 } 455 456 static void showerror( 457 {required buildcontext context, 458 required string message, 459 voidcallback? onpressed}) { 460 showdialog( 461 context context, 462 builder (buildcontext context) { 463 return alertdialog( 464 title const text("error!"), 465 content text(message), 466 actions \<widget>\[ 467 new elevatedbutton( 468 child const text("ok"), 469 onpressed () { 470 navigator of(context) pop(); 471 if (onpressed != null) { 472 onpressed(); 473 } 474 }, 475 ), 476 ], 477 ); 478 }, 479 ); 480 } 481 } 482 関数の debug debug パラメータが parse() initialize parse() initialize の場合、 true true であれば、parse api コールをコンソールに表示することができます。この設定はコードのデバッグに役立ちます。リリース版ではデバッグを無効にすることが賢明です。 2 テンプレートを back4app プロジェクトに接続する アプリケーション id とクライアントキーの資格情報を見つけるには、 back4app ウェブサイト https //www back4app com/ のアプリダッシュボードに移動します。 「main dart」にコードを更新し、back4appのプロジェクトのapplicationidとclientkeyの値を設定してください。 keyapplicationid = アプリid keyclientkey = クライアントキー プロジェクトを実行すると、アプリが画像のように読み込まれます。 3 セッションで現在のユーザーを取得するためのコード ユーザーログインまたはサインアップ機能は、 セッション セッション オブジェクトを作成し、ログインした ユーザー ユーザー を指し、有効なユーザーセッションをローカルストレージに保存します。 メソッドへの呼び出し currentuser currentuser はあなたの parseuser parseuser データと sessiontoken sessiontoken を session session オブジェクトのために正常に取得します。 ファイル hasuserlogged hasuserlogged の中で関数 main dart main dart を検索します。 コードを hasuserlogged hasuserlogged の中に置き換えます 1 parseuser? currentuser = await parseuser currentuser() as parseuser?; 2 if (currentuser == null) { 3 return false; 4 } 5 //checks whether the user's session token is valid 6 final parseresponse? parseresponse = 7 await parseuser getcurrentuserfromserver(currentuser sessiontoken!); 8 9 if (parseresponse? success == null || !parseresponse! success) { 10 //invalid session logout 11 await currentuser logout(); 12 return false; 13 } else { 14 return true; 15 } この関数を構築するには、次の手順に従ってください 次の parseuser currentuser() parseuser currentuser() 関数を呼び出します。これにより、 parseuser parseuser オブジェクトがローカルストレージから返されます。 もし parseuser parseuser が null の場合、アプリにアクティブなセッションを持つユーザーはいません。 もし parseuser parseuser が null でない場合、アプリにアクティブなセッションを持つユーザーがいます。 ユーザーのセッションは、ライフタイムがあるため、parse server で検証する必要があります。 トークンが無効な場合、現在のセッションをクリアするためにログアウト関数を呼び出す必要があり、ユーザーは再度ログインする必要があります。 完全な関数は次のようになります 1 future\<bool> hasuserlogged() async { 2 parseuser? currentuser = await parseuser currentuser() as parseuser?; 3 if (currentuser == null) { 4 return false; 5 } 6 //checks whether the user's session token is valid 7 final parseresponse? parseresponse = 8 await parseuser getcurrentuserfromserver(currentuser sessiontoken!); 9 10 if (parseresponse? success == null || !parseresponse! success) { 11 //invalid session logout 12 await currentuser logout(); 13 return false; 14 } else { 15 return true; 16 } 17 } ファイル getuser getuser の中で main dart main dart を探してください。 次のように getuser getuser の中のコードを置き換えてください 1 currentuser = await parseuser currentuser() as parseuser?; 2 return currentuser; この関数を構築するには、次の手順に従ってください 「 parseuser currentuser() parseuser currentuser() 」関数を呼び出します。これにより、 parseuser parseuser オブジェクトがローカルストレージから返されます。 完全な関数は次のようになります 1 future\<parseuser> getuser() async { 2 currentuser = await parseuser currentuser() as parseuser?; 3 return currentuser; 4 } テストするには、 run run ボタンをandroid studio/vscodeでクリックします。 サインアップまたはログインすると、次の画面にログインユーザーのユーザー名が表示されます。 アプリケーションを終了し、再度実行します。 有効なユーザーセッションが確認されると、ユーザーのユーザー名が表示される画面が表示されます。 完了です! このガイドの最後に、back4appを通じてparse serverのコア機能を使用して、アプリのセッションで現在のユーザーを取得できます!