Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

Flutter OAuth1 myth

37 views
Skip to first unread message

windingalong zhao

unread,
Sep 2, 2024, 4:43:45 PM9/2/24
to FatSecret Platform API
Hi team, I am trying to use flutter to make a API call with OAuth1, but there is an error in making the request token, error message as below, 

########################

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Connection failed
#0      IOClient.send (package:http/src/io_client.dart:94:7)
<asynchronous suspension>
#1      BaseClient._sendUnstreamed (package:http/src/base_client.dart:93:32)
<asynchronous suspension>
#2      Authorization.requestTemporaryCredentials (package:oauth1/src/authorization.dart:48:31)
<asynchronous suspension>
#3      FatSecretAPI.authenticate (package:fatsecret_app_829/fatsecret_api.dart:38:34)
<asynchronous suspension>
#4      _FatSecretHomePageState.build.<anonymous closure> (package:fatsecret_app_829/main.dart:41:17)
<asynchronous suspension>

########################

attaching the main.dart and fatsecret_api.dart as below. Any insight how to get it right?

Thanks.


------------------------
main.dart
-------

import 'package:flutter/material.dart'; import 'fatsecret_api.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'FatSecret API OAuth1 Example', theme: ThemeData( primarySwatch: Colors.blue, ), home: FatSecretHomePage(), ); } } class FatSecretHomePage extends StatefulWidget { @override _FatSecretHomePageState createState() => _FatSecretHomePageState(); } class _FatSecretHomePageState extends State<FatSecretHomePage> { final FatSecretAPI _fatSecretAPI = FatSecretAPI(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('FatSecret API OAuth1 Example'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ ElevatedButton( onPressed: () async { await _fatSecretAPI.authenticate(context); }, child: Text('Authenticate with FatSecret'), ), ElevatedButton( onPressed: () async { // Example parameters for a POST request to FatSecret API Map<String, String> parameters = { 'method': 'foods.search', 'search_expression': 'apple', 'format': 'json', }; await _fatSecretAPI.makeAuthenticatedPostRequest('', parameters); }, child: Text('Search Food'), ), ], ), ), ); } }



fatsecret_api.dart

----
import 'package:oauth1/oauth1.dart' as oauth1; import 'package:http/http.dart' as http; import 'package:url_launcher/url_launcher.dart'; import 'dart:convert'; import 'package:flutter/material.dart'; class FatSecretAPI { final String _consumerKey = 'XX'; // Replace with your Consumer Key final String _consumerSecret = 'XX'; // Replace with your Consumer Secret oauth1.Client? _client; Future<void> authenticate(BuildContext context) async { print('#### authenticate step'); // Set up OAuth1.0a credentials final platform = oauth1.Platform( 'https://www.fatsecret.com/oauth/request_token', 'https://www.fatsecret.com/oauth/access_token', 'https://www.fatsecret.com/oauth/authorize', oauth1.SignatureMethods.hmacSha1, ); final clientCredentials = oauth1.ClientCredentials(_consumerKey, _consumerSecret); print('#### clientcredentials'); // Step 1: Get request token final auth = oauth1.Authorization(clientCredentials, platform); print('#### auth'); //final requestTokenResponse = await auth.requestTemporaryCredentials('oob'); //try { // final requestTokenResponse = await auth.requestTemporaryCredentials('oob'); // Handle successful response //} catch (e) { // print('Error requesting temporary credentials: $e'); //} final requestTokenResponse = await auth.requestTemporaryCredentials('oob'); print('#### request token response'); final requestToken = requestTokenResponse.credentials.token; print('#### request token'); // Step 2: Redirect user to authorization URL in the browser final authorizationUrl = auth.getResourceOwnerAuthorizationURI(requestToken); print('#### url'); if (await canLaunch(authorizationUrl)) { print('launching'); await launch(authorizationUrl); print('launched'); } else { throw 'Could not launch $authorizationUrl'; print('Could not launch $authorizationUrl'); } // Step 3: Ask the user to input the verifier code String verifier = await _showVerifierInputDialog(context); // Step 4: Get access token final tokenCredentialsResponse = await auth.requestTokenCredentials( oauth1.Credentials(requestToken, requestTokenResponse.credentials.tokenSecret), verifier, ); _client = oauth1.Client( platform.signatureMethod, clientCredentials, tokenCredentialsResponse.credentials, ); print('Authentication successful. Access token obtained.'); } Future<void> makeAuthenticatedPostRequest(String endpoint, Map<String, String> parameters) async { if (_client == null) { print('Client is not authenticated. Please authenticate first.'); return; } final url = Uri.parse('https://platform.fatsecret.com/rest/server.api' + endpoint); // OAuth1.0a automatically handles the signing final response = await _client!.post(url, body: parameters); if (response.statusCode == 200) { print('Response data: ${response.body}'); } else { print('Request failed with status: ${response.statusCode}'); } } Future<String> _showVerifierInputDialog(BuildContext context) async { TextEditingController verifierController = TextEditingController(); return showDialog<String>( context: context, builder: (BuildContext context) { return AlertDialog( title: Text('Enter Verifier Code'), content: TextField( controller: verifierController, decoration: InputDecoration(hintText: "Enter verifier code here"), ), actions: <Widget>[ ElevatedButton( onPressed: () { Navigator.of(context).pop(verifierController.text); }, child: Text('Submit'), ), ], ); }, ).then((value) => value ?? ''); } }
Reply all
Reply to author
Forward
0 new messages