You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Flutter Web Auth_2获取Discord Bearer Token时重定向URI格式错误求助

解决Flutter Web Auth_2获取Discord Bearer Token时的"discord not valid formated well redirect uri"错误

核心问题定位

这个错误的根源是Redirect URI格式不符合Discord OAuth2的要求,同时你的代码和配置里还有几处逻辑错误,逐一拆解如下:

1. Callback URL Scheme格式错误

你当前把callbackUrlScheme设为http://com.example.sabadospotify,但Android自定义URL Scheme不能带http://前缀,必须是纯协议名(比如com.example.sabadospotify),而且Discord后台配置的Redirect URI必须和代码里的完全匹配。

2. AndroidManifest的Scheme配置错误

<data android:scheme="http://com.example.sabadospotify" /> 同样不能带http://,要改成纯协议名。

3. 代码里的其他逻辑问题

  • getGoogleAuthCode函数重复调用FlutterWebAuth2.authenticate,还存在无效的重复return语句
  • 全局变量casteo错误地把Future<String>强制转成String,会直接触发运行时错误
  • print(result1)语法写错了,而且异步逻辑完全没处理对
  • 按钮点击事件没串联授权和Token交换的流程,也没传递授权码
  • Discord授权请求里不该传client_secret——这个参数只在后端交换Token时用,前端授权步骤暴露它会有安全风险

修正后的配置和代码

1. 修正AndroidManifest.xml

<activity
    android:name="com.linusu.flutter_web_auth_2.CallbackActivity"
    android:exported="true">
    <intent-filter android:label="flutter_web_auth_2">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <!-- 去掉http://,只保留纯scheme -->
        <data android:scheme="com.example.sabadospotify" />
    </intent-filter>
</activity>

2. 修正Dart代码

import 'package:flutter/material.dart';
import 'package:flutter_web_auth_2/flutter_web_auth_2.dart';
import 'dart:convert' show jsonDecode;
import 'package:http/http.dart' as http;

// App配置变量
final discordClientId = '你的Discord Client ID';
final discordClientSecret = '你的Discord Client Secret';
// 修正为纯scheme,不带http://
final callbackUrlScheme = 'com.example.sabadospotify';
// 对应的Redirect URI,必须和Discord后台配置完全一致
final redirectUri = '$callbackUrlScheme:/';

// 构建Discord授权URL
final authUrl = Uri.https('discord.com', '/oauth2/authorize', {
  'response_type': 'code',
  'client_id': discordClientId,
  // 授权步骤不需要传client_secret,避免泄露
  'redirect_uri': redirectUri,
  'scope': 'email', // 可按需添加其他权限,比如identify
});

// 获取授权码
Future<String> getDiscordAuthCode() async {
  final resultUrl = await FlutterWebAuth2.authenticate(
    url: authUrl.toString(),
    callbackUrlScheme: callbackUrlScheme,
  );
  // 从回调URL里提取授权码
  final code = Uri.parse(resultUrl).queryParameters['code'];
  if (code == null) throw Exception('未获取到授权码');
  return code;
}

// 用授权码交换Bearer Token
Future<String> exchangeCodeForToken(String code) async {
  final response = await http.post(
    Uri.parse('https://discord.com/api/oauth2/token'),
    headers: {'Content-Type': 'application/x-www-form-urlencoded'},
    body: {
      'code': code,
      'client_id': discordClientId,
      'client_secret': discordClientSecret,
      'redirect_uri': redirectUri,
      'grant_type': 'authorization_code',
    },
  );

  if (response.statusCode != 200) {
    throw Exception('Token交换失败: ${response.body}');
  }

  final body = jsonDecode(response.body);
  final accessToken = body['access_token'] as String;
  return accessToken;
}

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('Discord 登录')),
        body: Center(
          child: ElevatedButton(
            child: const Text('Sign in with Discord'),
            onPressed: () async {
              try {
                // 先获取授权码
                final code = await getDiscordAuthCode();
                // 再交换Token
                final token = await exchangeCodeForToken(code);
                print('获取到Bearer Token: $token');
                // 这里可以加后续逻辑,比如保存Token、跳转页面等
              } catch (e) {
                print('登录失败: $e');
                // 处理错误,比如提示用户
              }
            },
          ),
        ),
      ),
    );
  }
}

最后必做的配置

  1. 登录Discord开发者后台,找到你的应用
  2. 进入OAuth2 -> General页面
  3. 在Redirects列表里添加com.example.sabadospotify:/(和代码里的redirectUri完全一致)
  4. 保存配置

内容的提问来源于stack exchange,提问作者oshju

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 19:31:02