如何在Flutter应用中正确设置redirect_uri? [英] How to correctly set redirect_uri in Flutter app?

查看:125
本文介绍了如何在Flutter应用中正确设置redirect_uri?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过Flutter应用将用户登录到Google API,但无法使其自动获取令牌.我最接近的是在auth屏幕中看到令牌字符串,并被要求将其复制/粘贴回应用程序中.我怀疑它与redirect_uri参数有关.

I'm trying to log the user into a Google API from my Flutter app, but can't get it to automatically fetch the token. The closest I got was to see the token string in the auth screen and be asked to copy/paste it back into the app. I suspect it's related to the redirect_uri parameter.

我尝试同时使用 oauth2_client

I attempted with both oauth2_client and flutter_appauth and it's pretty much the same outcome. When setting up the client, if I use the first redirect_uri provided by Google urn:ietf:wg:oauth:2.0:oob, after granting the permissions it shows the token in the auth screen and instructs the user to copy it and paste it back in the app. If I use the uri that I set in AndroidManifest.xml and build.gradle, instead of the consent screen, I get this message in the browser:

" redirect_url的无效参数值:缺少方案:ai.autonet.afterme"

"Invalid parameter value for redirect_url: Missing scheme: ai.autonet.afterme"

最后,如果我使用"http://localhost" (由Google提供的第二个uri),则会收到请求超时".

Lastly, if I use "http://localhost" (the second uri provided by Google), I get "request timed out".

我在Google方面的客户端配置如下:

My client configuration from Google's side looks like this:

"client_id":"somethingsomething.apps.googleusercontent.com","project_id":"afterme-850af","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","redirect_uris":["urn:ietf:wg:oauth:2.0:oob","http://localhost"]

这是flutter_appauth实现的最简单版本:

Here is the simplest version of the flutter_appauth implementation:

main.dart
import 'package:flutter/material.dart';
    import 'package:flutter_appauth/flutter_appauth.dart';
    import 'package:oauth2_client/access_token_response.dart';
    import 'package:http/http.dart' as http;

    const AUTH_ENDIPOINT = 'https://accounts.google.com/o/oauth2/auth';
    const CLIENT_ID =
        'somethingsomething.apps.googleusercontent.com';
    const REDIRECT_URI = 'ai.autonet.afterme';
    const TOKEN_ENDPOINT = "https://oauth2.googleapis.com/token";
    var scopes = [
        "https://www.googleapis.com/auth/youtube",
        "https://www.googleapis.com/auth/youtube.upload",
    ];
    void main() {
        runApp(MyApp());
    }

    var httpClient = http.Client();

    class MyApp extends StatelessWidget {
        @override
        Widget build(BuildContext context) {
        return MaterialApp(
            title: 'Flutter Demo',
            theme: ThemeData(
            primarySwatch: Colors.blue,
            visualDensity: VisualDensity.adaptivePlatformDensity,
            ),
            home: MyHomePage(title: 'Flutter Demo Home Page'),
        );
        }
    }

    class MyHomePage extends StatefulWidget {
        MyHomePage({Key key, this.title}) : super(key: key);

        final String title;
        FlutterAppAuth appAuth = FlutterAppAuth();

        authorize() async {
        final AuthorizationTokenResponse result =
            await appAuth.authorizeAndExchangeCode(AuthorizationTokenRequest(
                CLIENT_ID, REDIRECT_URI,
                serviceConfiguration: AuthorizationServiceConfiguration(
                    AUTH_ENDPOINT,
                    TOKEN_ENDPOINT),
                scopes: scopes));
        print(result.accessToken.toString());
        }

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

    class _MyHomePageState extends State<MyHomePage> {
        getResources() async {
        http.Response resp = await httpClient
            .get('GET https://www.googleapis.com/youtube/v3/videos');
        print(resp.body);
        }


        @override
        Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
            title: Text(widget.title),
            ),
            body: Center(
            child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                
                RaisedButton(
                    child: Text("Permission"), onPressed: () => widget.authorize()),
                ],
            ),
            ),
            
        );
        }
    }
----------------------------------------------------------------
AndroidManifest.xml:
        <manifest xmlns:android="http://schemas.android.com/apk/res/android"
            package="ai.autonet.afterme">
            
            <!-- io.flutter.app.FlutterApplication is an android.app.Application that
                calls FlutterMain.startInitialization(this); in its onCreate method.
                In most cases you can leave this as-is, but you if you want to provide
                additional functionality it is fine to subclass or reimplement
                FlutterApplication and put your custom class here. -->
            <application
                android:name="io.flutter.app.FlutterApplication"
                android:label="afterme"
                android:icon="@mipmap/ic_launcher">
                <activity android:name="com.linusu.flutter_web_auth.CallbackActivity" >
                <intent-filter android:label="flutter_web_auth">
                    <action android:name="android.intent.action.VIEW" />
                    <category android:name="android.intent.category.DEFAULT" />
                    <category android:name="android.intent.category.BROWSABLE" />
                    <data android:scheme="ai.autonet.afterme" />
                </intent-filter>
            </activity>
                <activity
                    android:name=".MainActivity"
                    android:launchMode="singleTop"
                    android:theme="@style/LaunchTheme"
                    android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
                    android:hardwareAccelerated="true"
                    android:windowSoftInputMode="adjustResize">
                    <!-- Specifies an Android theme to apply to this Activity as soon as
                        the Android process has started. This theme is visible to the user
                        while the Flutter UI initializes. After that, this theme continues
                        to determine the Window background behind the Flutter UI. -->
                    <meta-data
                    android:name="io.flutter.embedding.android.NormalTheme"
                    android:resource="@style/NormalTheme"
                    />
                    <!-- Displays an Android View that continues showing the launch screen
                        Drawable until Flutter paints its first frame, then this splash
                        screen fades out. A splash screen is useful to avoid any visual
                        gap between the end of Android's launch screen and the painting of
                        Flutter's first frame. -->
                    <meta-data
                    android:name="io.flutter.embedding.android.SplashScreenDrawable"
                    android:resource="@drawable/launch_background"
                    />
                    <intent-filter>
                        <action android:name="android.intent.action.MAIN"/>
                        <category android:name="android.intent.category.LAUNCHER"/>
                    </intent-filter>
                </activity>
                <!-- Don't delete the meta-data below.
                    This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
                <meta-data
                    android:name="flutterEmbedding"
                    android:value="2" />
            </application>
        </manifest>
-------------------------------------------------------------------------------------
build.gradle:
  ...
    defaultConfig {
        applicationId "ai.autonet.afterme"
        minSdkVersion 18
        targetSdkVersion 29
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
        manifestPlaceholders = [
        'appAuthRedirectScheme': 'ai.autonet.afterme'
        ]
    }
    ...

任何帮助都将得到重视.

Any help would be valued.

推荐答案

您是否尝试过在方案的末尾添加://?我不确定您是否向Google提供了有效的方案名称.

Have you tried adding :// to the end of your Scheme? I'm not sure you are providing a valid scheme name to Google.

您可以尝试 ai.autonet.afterme://还是 ai.autonet.afterme://auth 吗?

这篇关于如何在Flutter应用中正确设置redirect_uri?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆