refactor: Update Twitter OAuth 2.0 PKCE flow for dynamic redirect URI and public client authentication, replace SVG back button with a native icon, and enhance Twitter login error reporting.
This commit is contained in:
@@ -3,14 +3,20 @@ import 'dart:math';
|
||||
|
||||
import 'package:crypto/crypto.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:real_estate_mobile/config/app_config.dart';
|
||||
|
||||
/// Twitter OAuth 2.0 PKCE flow for mobile.
|
||||
class TwitterAuthService {
|
||||
static const _clientId = 'eWEzaDJ0al9lX1diOGY0ejRYeXM6MTpjaQ';
|
||||
// Must match the callback URL configured in Twitter Developer Portal
|
||||
static const _redirectUri = 'https://dev.re-quest.com/auth/callback/twitter';
|
||||
static const _scope = 'tweet.read users.read offline.access';
|
||||
|
||||
/// Derive redirect URI from API base URL (matches next-auth callback)
|
||||
static String get _redirectUri {
|
||||
final apiUrl = AppConfig.apiBaseUrl; // e.g. https://dev.re-quest.com/api/v1
|
||||
final base = apiUrl.replaceAll(RegExp(r'/api/v1/?$'), '');
|
||||
return '$base/api/auth/callback/twitter';
|
||||
}
|
||||
|
||||
late final String _codeVerifier;
|
||||
late final String _codeChallenge;
|
||||
late final String _stateParam;
|
||||
@@ -51,21 +57,20 @@ class TwitterAuthService {
|
||||
Future<Map<String, dynamic>?> exchangeCodeForUser(String code) async {
|
||||
final dio = Dio();
|
||||
|
||||
// Exchange code for access token
|
||||
// Exchange code for access token (PKCE public client — client_id in body)
|
||||
final tokenBody =
|
||||
'code=${Uri.encodeComponent(code)}'
|
||||
'&grant_type=authorization_code'
|
||||
'&client_id=${Uri.encodeComponent(_clientId)}'
|
||||
'&redirect_uri=${Uri.encodeComponent(_redirectUri)}'
|
||||
'&code_verifier=${Uri.encodeComponent(_codeVerifier)}';
|
||||
|
||||
final tokenResponse = await dio.post(
|
||||
'https://api.twitter.com/2/oauth2/token',
|
||||
options: Options(
|
||||
contentType: 'application/x-www-form-urlencoded',
|
||||
headers: {
|
||||
'Authorization': 'Basic ${base64Encode(utf8.encode('$_clientId:'))}',
|
||||
},
|
||||
),
|
||||
data: {
|
||||
'code': code,
|
||||
'grant_type': 'authorization_code',
|
||||
'redirect_uri': _redirectUri,
|
||||
'code_verifier': _codeVerifier,
|
||||
},
|
||||
data: tokenBody,
|
||||
);
|
||||
|
||||
final accessToken = tokenResponse.data['access_token'] as String?;
|
||||
|
||||
Reference in New Issue
Block a user