Dart/Flutter PostFrameCallBack 和 Uri.base.origin

Dart/Flutter PostFrameCallBack and Uri.base.origin

我正在尝试实现一个系统,用户将调用外部网站进行登录并在 url 中发回密钥。如果我在 Main.dart 中调用此应用程序屏幕作为主屏幕时调用此代码块,它会完全按预期工作:代码检查 'token' 是否在 URL 中,如果不在将重定向到外部站点以供用户登录,检索密钥并发送回 flutter 屏幕,现在它可以在执行 initState() 时找到令牌。

import 'dart:convert';
import 'package:universal_html/html.dart' as html;
import 'package:flutter/material.dart';

class LoginScreen extends StatefulWidget {
  static final routeName = "/login";
  const LoginScreen({Key? key}) : super(key: key);

  @override
  _LoginScreenState createState() => _LoginScreenState();
}

class _LoginScreenState extends State<LoginScreen> {
  var tempToken;
        @override
          void initState() {
            super.initState();
            final currentUrl = Uri.base;
            print(currentUrl);
            if (currentUrl.queryParameters['token'] == null) {
              print('looking for token');
              // You are not connected so redirect to the login
              WidgetsBinding.instance!.addPostFrameCallback((_) async {
                html.window.location.assign(
                  'http://localhost:8080/auth/?source=app&after=${base64Encode(utf8.encode(currentUrl.origin))}', //where i send in the redirect back
                );
              });
            } else {
              tempToken = currentUrl.queryParameters['token'].toString();
              print(tempToken);
            }
          }
    
       @override
         Widget build(BuildContext context) {
          return const Center(child: CircularProgressIndicator());
      }

问题 当我尝试从我的应用程序的欢迎屏幕重定向到此屏幕时,问题就出现了。代码的设置方式会将我发送回 currentUrl,它将是“/”而不是“/login”,将我发送到欢迎屏幕,并且令牌不再位于 url 中。知道我应该从这里去哪里吗?

我们发现在 Flutter 网络应用程序启动后立即抓取完整内容很有用 href,代码如下:

Map<String, String>? initialQueryParameters;

void main() {
  initialQueryParameters = getHref().queryParameters;
  runApp(const Controller());
}

这会在您创建 MaterialApp 之前捕获任何查询参数的值,并开始路由到页面,这将更改 href.

我们的流程是:

  • index.html
  • 一些 oauth 网站,重定向回
  • index.html?someParam=someValue(或者可以是 index.html/#/route?...)

Flutter应用第一次运行时,someParam为null。重定向回来后,应用程序第二次运行,但现在 someParam 设置为 someValue。因为这是在启动时抓取并存储在全局 initialQueryParameters 中,所以可以在需要时检查它,即使在路由和导航可能重写 href 之后也可用。