furaiev / amazon-cognito-identity-dart-2 Goto Github PK
View Code? Open in Web Editor NEWUnofficial Amazon Cognito Identity Provider Dart SDK, to easily add user sign-up and sign-in to your mobile and web apps with AWS.
License: MIT License
Unofficial Amazon Cognito Identity Provider Dart SDK, to easily add user sign-up and sign-in to your mobile and web apps with AWS.
License: MIT License
I'm making a POST request to Amazon S3 by sending an image together; however, when uploading the image, it assumes the default value as if I had not sent the content metadata, causing it to be downloaded when opening the image in the browser.
Code:
final _client = Dio( );
final int length = await image.length();
final String filename = '$path${DateTime.now().millisecondsSinceEpoch}.jpeg';
final String key = filename;
final Policy policy = Policy.fromS3PreSignedPost(
key,
bucketId,
500,
accessKey,
length,
sessionToken,
region: region,
);
final List<int> signKey = SigV4.calculateSigningKey(secretKey, policy.datetime, region, service);
final String signature = SigV4.calculateSignature(signKey, policy.encode( ));
final FormData formData = FormData.fromMap({
'key': policy.key,
'acl': 'public-read',
'X-Amz-Algorithm': 'AWS4-HMAC-SHA256',
'X-Amz-Credential': policy.credential,
'X-Amz-Date': policy.datetime,
'Policy': policy.encode(),
'X-Amz-Signature': signature,
'x-amz-security-token': sessionToken,
'file': await MultipartFile.fromFile(
image.path,
filename: filename,
contentType: MediaType('image', 'jpeg'),
),
});
await _client.post(post, data: formData);
Hi,
i have a Problem with the Encoding and i have no clue where its coming from.
Package: 2 0.1.12+3
What iam Doing:
Get request against API Gateway.
code:
final signedRequest = new SigV4Request(
awsSigV4Client,
method: 'GET',
path: "/path/$querystring",
headers: new Map<String, String>.from({}),
queryParams: new Map<String, String>.from({}),
);
Response response;
response = await http.get(
signedRequest.url,
options: Options(
headers: signedRequest.headers,
),
);
When i pass no special Characters it works, but as soon i pass characters like &ÄÜÖ i receive an error:
"The request signature we calculated does not match the signature you provided
The Canonical String for this request should have been
'GET
/path/%25C3%25A4 (<<< is an double encoded 'ä')
"
it seems like it is double encoded and i have no clue where to start whats going on here.
Any thoughts?
Best Regards,
I'm getting this exception on production apk in Pixel3A Android10
2020-03-30 10:03:58.923 2263-2289/? E/flutter: [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: type '_OneByteString' is not a subtype of type 'int' of 'index'
#0 CognitoIdentityId.getIdentityId (package:amazon_cognito_identity_dart_2/src/cognito_identity_id.dart:51)
<asynchronous suspension>
#1 CognitoCredentials._getAwsCredentials (package:amazon_cognito_identity_dart_2/src/cognito_credentials.dart:52)
<asynchronous suspension>
#2 CognitoCredentials.getAwsCredentials (package:amazon_cognito_identity_dart_2/src/cognito_credentials.dart:38)
<asynchronous suspension>
Hi,
Great work with the project so far, I just wanna suggest that one of the items on the product roadmap could be: AWS Pinpoint.
Have a great day,
Cristian
I use this package to signed my http request for amazon lex service like this :
AwsSigV4Client client=AwsSigV4Client(
kAccessKey,
kSecretKey,
'https://runtime.lex.us-east-1.amazonaws.com',
region: 'us-east-1',
serviceName: 'lex',
);
final signedRequest = new SigV4Request(
client,
method: 'POST',
path: '/bot/MyBotName/alias/BETA/user/MyUser/text',
body: new Map<String, dynamic>.from({"inputText": "hi"}),
);
var response = await http.post(
signedRequest.url,
headers: signedRequest.headers,
body: signedRequest.body,
);
print(response.body.toString());
but i got this message from server :
{"message":"The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details."}
also i cant see :
X-Amz-Content-Sha256
in headers .
am i miss something ?
instead of
import 'package:amazon_cognito_identity_dart/cognito.dart';
it should be
import 'package:amazon_cognito_identity_dart_2/cognito.dart';
prevents copy and paste
and it's recommended against
Hi,
Is there any way that i can respond to auth challenge SELECT_MFA_TYPE?.. I was trying to reuse sendCustomChallengeAnswer method, but the challengeName is hardcoded as 'CUSTOM_CHALLENGE'.
Can you please provide a method that accepts both the challenge name and answer?.. This way, in future we can support any type of auth challenges.
Thank you
both
final attributes = await _cognitoUser.getUserAttributes();
List attributes = await _cognitoUser.getUserAttributes();
getting this error:
_TypeError (type 'List' is not a subtype of type 'FutureOr<List>')
Kind of new to fluttter and all but strict type casting seems to be giving quite a bit of error recently.
Changing
Future<List> getUserAttributes() async {
to
Future getUserAttributes() async {
does work but I'm not really sure if it should be done this way.
Hi @furaiev,
Thanks for this great library & updates on it!
I'm wondering if there is a way to get the upload progress through s3 send(). Right now it only returns an empty response after image upload completion.
Is there any way to see if the user has multiple factor authentication activated or not?
Hi @furaiev, we enabled MFA while sign-in and we use sendMFACode method to achieve it.
Can we have an another method to request for MFA code when we intend to do some (secured) transactions/actions?
Thanks in advance.
I'm new to Flutter, so wondering about the example app's use of FutureBuilder
, and calling _getValues
in the build
method. It seems like you'd only need to setup the UserService
once, in an initState
, instead of re-creating this and doing the auth check on every build method invocation? Further, when the increment button is pressed, you will wind up doing a second fetch of the counter, which is needless and would just double your Lambda invocations. i.e. it's incremented in the _incrementCounter
and gets the updated counter there, but then sets the state, causing a rebuild which then fetches the counter again in _getValues
. I added debug printing to my own code that follows the pattern of the sample app, and I see that happen at least.
I realize that technically a user's account could be deleted or logged out of all tokens via some other use, and thus one could argue that checking their auth on every render is the most secure, but it seems excessive and in a case like this where you also call a Lambda, like you're doing more than you need. Can you thus shed some light on this design and why it is favored over using initState
to set all this up instead - since I'm new to this, I'm wondering if I'm missing something or if it's just a choice for the example, or? Thanks for this flutter plugin, it's working well for me so far!
when I try to use confirmRegistration from CognitoUser I get the following error:
{
"__type": "NotAuthorizedException",
"message": "Unable to verify secret hash for client ***********"
}
then I debug the lib and figured it is not sending the client secret in this call, it can be fixed doing like the signUp method
if (_clientSecret != null) {
params['SecretHash'] = CognitoUser.calculateClientSecretHash(username, _clientId, _clientSecret);
}
The README from the project mentions "Please note that this package is not production ready."
Is there a way we could understand why not? So that we could help contribute.
Thanks for all the hard work forking and updating the original project!
Thanks for the package. I am trying to use it. I am almost there but stuck at specific issue around SignedRequest to API Gateway (Authenticated by IAM Role)
This is what I am doing:
final GoogleSignIn googleSignIn = GoogleSignIn(scopes: ['email']);
final GoogleSignInAccount googleSignInAccount = await googleSignIn.signIn();
GoogleSignInAuthentication googleSignInAuthentication = await googleSignInAccount.authentication;
CognitoCredentials _credential = new CognitoCredentials(identityPoolId, userPool);
await _credential.getAwsCredentials(googleSignInAuthentication.idToken, 'accounts.google.com');
final awsSigV4Client = new AwsSigV4Client(
_credential.accessKeyId, _credential.secretAccessKey, endpoint,
sessionToken: _credential.sessionToken,
region: region);
final signedRequest = new SigV4Request(awsSigV4Client,
method: 'POST',
path: '/my-path/',
body: new Map<String, String>.from({'field_1': 'field_value'})
);
http.Response response = await http.post(
signedRequest.url,
headers: signedRequest.headers,
body: signedRequest.body,
);
print(response.body);
print(response.statusCode);
print(response.headers);
I am getting following error:
message":"The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.\n\nThe Canonical String for this request should have been\n'
If I remove payload (body) or pass blank body, it passes the AWS checks (working). As soon as I put body, it fails. I tried different combinations of the map, still the same error.
I am sure I must be making very trivial mistake somewhere but I couldn't figure it out.
Pls let me know if any one of you encounter similar issue or see something obvious. Happy to provide more details. Thanks.
As i am trying to sign in with apple everything work fine but i see that app name is displaying null
in the apple native sheet.
In mobile when users apple account is already signed in device settings.
There are some open issues in other js packages.
https://developer.apple.com/forums/thread/129899
aws-amplify/amplify-js#4580
Please fix the issue in this package . Thanks in advance
class Cognito {
static const _userPoolId = 'xxx';
static const _clientId = 'xxx';
static const _clientSecret = 'xxx';
final CognitoUserPool userPool = new CognitoUserPool(_userPoolId, _clientId, clientSecret: _clientSecret);
static final Cognito _instance = Cognito._internal();
factory Cognito() {
return _instance;
}
Cognito._internal();
Future signUpAndGetToken(String email, String password) async {
await userPool.signUp(email, password);
return await signInAndGetToken(email, password);
}
Future signInAndGetToken(String email, String password) async {
final cognitoUser = new CognitoUser(email, new Cognito().userPool, clientSecret: _clientSecret);
final authDetails = new AuthenticationDetails(
username: email,
password: password,
);
CognitoUserSession session = await cognitoUser.authenticateUser(authDetails);
return session.getAccessToken().getJwtToken();
}
I'm able to sign up a new user without an error, but the CognitoUserSession session = await cognitoUser.authenticateUser(authDetails);
results in name: NotAuthorizedException, message: Unable to verify secret hash for client
I'm passing the same client secret in both the call to signUp and authenticateUser, so why would signUp be working but not authenticateUser?
I looked through the documentation and it's not clear whether this library has support for signing in via Google, Facebook, etc on mobile devices. I assume that there must be a way to pop up a browser, display the third party sign on page, and then redirect back to the app, but is that something that this library can facilitate or support?
Hi,
how can I authenticate user with Google using getAWSCredentials method? In the documentation there is en example for Facebook, saying that I need to pass 'graph.facebook.com' as a second parameter. I'm new to social auth and I do not know what is equivalent for that for Google or where actually search for it.
Just to add, I do not manage AWS Pools, I only do mobile app using whatever I am provided from AWS team.
Hi,
tried the example with API GW and Post Method but it was not working. I had to add an additional header with Content-Type: application/json; charset=utf-8
final signedRequest = new SigV4Request(awsSigV4Client,
method: 'POST',
path: 'xx',
headers: new Map<String, String>.from(
{"Content-Type": "application/json; charset=utf-8"}),
queryParams: new Map<String, String>.from({}),
body: new Map<String, dynamic>.from({'color': 'blue'}));
Cheers
There is not currently a way to refresh a user's session and their access token.
Hi,
I am unable to upload images using the library.
I m getting the below response
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>3881BA8E9D4EAD4B</RequestId><HostId>EIi9mLd/oUOTw1+pOzGnC9fbrdbTiSLGJAwVJUjJLByglccc2yfPti2LKkkISq71eWx+QvqOjuM=</HostId></Error>
The code for upload is as follows :
static Future<String> uploadFile({File file}) async {
CognitoUserPool userPool = CognitoUserPool(
kUserPoolID,
kClientID,
);
CognitoCredentials credentials = CognitoCredentials(
kIdentityPoolID,
userPool,
);
String response;
try {
final length = await file.length();
final stream = file.openRead();
final String fileName = path.basename(file.path);
final uri = Uri.parse(
ks3Endpoint,
);
final req = http.MultipartRequest(
kPOST,
uri,
);
String mimeType = mime(fileName);
List<String> mimeTypes = mimeType.split('/');
final multipartFile = http.MultipartFile(
'file',
stream,
length,
filename: fileName,
contentType: MediaType(
mimeTypes[0],
mimeTypes[1],
),
);
final token = await AppSyncConfig.getIdToken();
await credentials.getAwsCredentials(
token,
);
final String usrIdentityId = credentials.userIdentityId;
final String bucketKey = '$kBucketKey/$usrIdentityId/$fileName';
final policy = Policy.fromS3PreSignedPost(
bucketKey,
kBucketID,
15,
credentials.accessKeyId,
length,
credentials.sessionToken,
region: kRegion,
);
final key = SigV4.calculateSigningKey(
credentials.secretAccessKey,
policy.datetime,
kRegion,
's3',
);
final signature = SigV4.calculateSignature(
key,
policy.encode(),
);
req.fields["key"] = policy.key;
req.fields["acl"] = "public-read";
req.fields["X-Amz-Credential"] = policy.credential;
req.fields["X-Amz-Algorithm"] = "AWS4-HMAC-SHA256";
req.fields["X-Amz-Date"] = policy.datetime;
req.fields["Policy"] = policy.encode();
req.fields["X-Amz-Signature"] = signature;
req.fields["x-amz-security-token"] = credentials.sessionToken;
req.files.add(multipartFile);
final res = await req.send();
if (res.statusCode == 204) {
response = kSuccess;
} else {
response = res.statusCode.toString();
}
} catch (e) {
response = e.toString();
}
print(response);
return response;
}
Policy class
import 'dart:convert';
import 'package:amazon_cognito_identity_dart_2/sig_v4.dart';
class Policy {
String expiration;
String region;
String bucket;
String key;
String credential;
String datetime;
String sessionToken;
int maxFileSize;
Policy(this.key, this.bucket, this.datetime, this.expiration, this.credential,
this.maxFileSize, this.sessionToken,
{this.region = 'us-west-2'});
factory Policy.fromS3PreSignedPost(
String key,
String bucket,
int expiryMinutes,
String accessKeyId,
int maxFileSize,
String sessionToken,
{String region}) {
final datetime = SigV4.generateDatetime();
final expiration = (DateTime.now())
.add(Duration(minutes: expiryMinutes))
.toUtc()
.toString()
.split(' ')
.join('T');
final cred =
'$accessKeyId/${SigV4.buildCredentialScope(datetime, region, 's3')}';
final p = Policy(
key, bucket, datetime, expiration, cred, maxFileSize, sessionToken,
region: region);
return p;
}
String encode() {
final bytes = utf8.encode(toString());
return base64.encode(bytes);
}
@override
String toString() {
// Safe to remove the "acl" line if your bucket has no ACL permissions
return '''
{ "expiration": "${this.expiration}",
"conditions": [
{"bucket": "${this.bucket}"},
["starts-with", "\$key", "${this.key}"],
{"acl": "public-read"},
["content-length-range", 1, ${this.maxFileSize}],
{"x-amz-credential": "${this.credential}"},
{"x-amz-algorithm": "AWS4-HMAC-SHA256"},
{"x-amz-date": "${this.datetime}" },
{"x-amz-security-token": "${this.sessionToken}" }
]
}
''';
}
}
Hi,
first of all: Thank you for this package, it has been working flawlessly for us 👍
However, we have a minor question/issue: Is there a reason for CognitoUser.updateAttributes
and CognitoUser.deleteAttributes
not returning a Future
of some kind (maybe void
)?
We're trying to await
the user attribute update before updating the UI, however Dart will show a warning info: 'await' applied to 'void', which is not a 'Future'. (await_only_futures) ...
, although it looks like it works anyway.
Cheers
Trying to add facebook login with AWS Cognito. After loggin using https://pub.dev/packages/flutter_facebook_login I am trying to pass the details to AWS. But its throwing error of
Exception has occurred. CognitoClientException (CognitoClientException{statusCode: 400, code: NotAuthorizedException, name: NotAuthorizedException, message: Token is not from a supported provider of this identity pool.})
What am I doing wrong?
_loginWithFB() async{
final result = await facebookLogin.logIn(['email']);
switch (result.status) {
case FacebookLoginStatus.loggedIn:
final token = result.accessToken.token;
final graphResponse = await http.get('https://graph.facebook.com/v2.12/me?fields=name,picture,email&access_token=${token}');
final profile = JSON.jsonDecode(graphResponse.body);
print(profile);
final _userPool = new CognitoUserPool('ap-south-1_XXXXXXXXX', 'xxxxxxxxxxxxxxxxxxxxx');
final _credential = new CognitoCredentials('ap-south-1:xxxxxxxxx-xxxx-xxxx-xxxxxxxxxxx', _userPool);
await _credential.getAwsCredentials(token, 'graph.facebook.com');
print(_credential.sessionToken);
setState(() {
userProfile = profile;
_isLoggedIn = true;
});
break;
case FacebookLoginStatus.cancelledByUser:
setState(() => _isLoggedIn = false );
break;
case FacebookLoginStatus.error:
setState(() => _isLoggedIn = false );
break;
}
}
Thanks in advance.
When I tried your example with 2 existing users that I have in my pool (the 2 users are already with 'Enabled / CONFIRMED' status in Cognito), I got the CognitoUserConfirmationNecessaryException but I don't understand why this exception is thrown. And the same when I tried in my app. And the variable challengeName is null when I check it in the exception.
This is my code :
final cognitoUser = CognitoUser(_username, userPool, storage: userPool.storage);
final authDetails = AuthenticationDetails(
username: _username,
password: _password,
);
CognitoUserSession session;
try {
session = await cognitoUser.authenticateUser(authDetails);
} on CognitoUserConfirmationNecessaryException catch (e) {
print(e.challengeName); -> null
print(e.message); -> User Confirmation Necessary
print(e.signInUserSession.isValid()); -> true
} catch (e) {
print(e);
}
Hey, have you tried inviting the coders that forked the original version of this project? They seem to have made a lot of contributions in their own forks.
Hello, everyone,
i am currently in the process of creating an app with a passwordless login. i found the following page:
https://techinscribed.com/passwordless-phone-number-authentication-using-aws-amplify-cognito/
I can also create an account with Lambda but unfortunately I can't login.
Here is my code and the error.
Future<CognitoUserSession> signIn(String phoneNumber) async { final cognitoUser = new CognitoUser(phoneNumber, _userPool); final authDetails = new AuthenticationDetails( username: phoneNumber ); CognitoUserSession session; try { session = await cognitoUser.authenticateUser(authDetails); } on CognitoUserNewPasswordRequiredException catch (e) { // handle New Password challenge print('handle New Password challenge $e'); } on CognitoUserMfaRequiredException catch (e) { // handle SMS_MFA challenge print('SMS_MFA challenge $e'); } on CognitoUserSelectMfaTypeException catch (e) { // handle SELECT_MFA_TYPE challenge print('SELECT_MFA_TYPE challenge $e'); } on CognitoUserMfaSetupException catch (e) { // handle MFA_SETUP challenge print('MFA_SETUP challenge $e'); } on CognitoUserTotpRequiredException catch (e) { // handle SOFTWARE_TOKEN_MFA challenge print('SOFTWARE_TOKEN_MFA challenge $e'); } on CognitoUserCustomChallengeException catch (e) { // handle CUSTOM_CHALLENGE challenge print('CUSTOM_CHALLENGE challenge $e'); } on CognitoUserConfirmationNecessaryException catch (e) { // handle User Confirmation Necessary print('User Confirmation Necessary $e'); } on CognitoClientException catch (e) { // handle Wrong Username and Password and Cognito Client print('Wrong Username and Password and Cognito Client $e'); } catch (e) { print('over error $e'); } //print(session.getAccessToken().getJwtToken()); return (session); }
Error
Wrong Username and Password and Cognito Client CognitoClientException{statusCode: 400, code: InvalidParameterException, name: InvalidParameterException, message: USER_SRP_AUTH is not enabled for the client.}
Is it possible that this type of login is not yet supported?
Hi Team,
I referred the code from Use-case 19 for signing in using google account.
As a first step, I am launched to the Google Login screen(asking only email-Id). On entering the google account id and click on login, i am redirected to the error page saying "Couldn't sign you in. The browser or app may not be secure".
This is happening only in iOS and not in android.
Kindly help in sorting this out. Thanks.
I follow the example app, and implement it to my app.
Once publish it, got an issue after create a release version.
After the user session is over (1 hour after), user no longer able to access the app.
the _getValues was throwing error :
"error type '_onebytestring' is not a subtype of type 'int' of 'index'"
I though there's something wrong with my code.
But when I try release the example, the same thing happen.
Secure Counter page & Login page always show "Loading..."
When check it, the actual error came from _cognitoUser.getSession() method.
I honestly don't know what happen here (I'm new to Flutter)
It seem, this issue not happen on debug mode, only when release.
Originally posted by @erw13n in #24 (comment)
Hello,
When I try to get the currentUser() from Page to Page I got this error.
flutter: The error;
flutter: NoSuchMethodError: The method 'getSession' was called on null.Receiver: null
Here my code
Future<UserService> _getValues() async {
try {
final user = await userPoolSettings.getCurrentUser();
final session = await user.getSession();
print(session);
} catch (e) {
print("The error; ");
print(e);
}
return _userService;
}
My userPool definition is like this, with great credentials
static final userPoolSettings = new CognitoUserPool(
xxxxxxxxx, xxxxxx);
After authenticating and using the Cognito credentials for a little time (along with other AWS services), when I try to retrieve them after an app hot restart, I get the following error and I'm no more able to use them to access the other AWS services.
Failed assertion: line 27 pos 12: 'accessKey != null': is not true.
However, I noticed that the getAwsCredentials()
method gets called twice: while the first time it returns null keys and tokens, the second time they are correct. If I hot reload after the hot restart that gets me null keys, I get valid keys and tokens at the first call.
I am pretty new to this package, so I might be making mistakes in my code, even though it is very basic. Here it is:
Future<CognitoCredentials> getCredentials() async {
if (_cognitoUser == null || _session == null) return null;
_credentials = CognitoCredentials(_identityPoolId, _userPool);
await _credentials.getAwsCredentials(_session.getIdToken().getJwtToken());
return _credentials;
}
Am I wrong with my code or is there an error in the package?
I used the following code to authenticate user:
final authDetails = AuthenticationDetails(
username: email,
authParameters: List(),
validationData: {},
password: password);
try {
_session = await _cognitoUser.authenticateUser(authDetails);
} on CognitoUserCustomChallengeException catch (e) {
// handle custom challenage
print('custom challenage $e');
} on Error catch (e) {
print('Error $e');
}
And then I get the error on IE 11.
Unsupported operation: No source of cryptographically secure random numbers available
It works fine on FireFox, Chrome, Edge.
Do you have any suggestion to fix this issue? Could it relate to Crypto package?
Dear Developer,
I have an authenticated token and identity id from the server response.
By using that token and identity id, we can get credential information by using
DeveloperAuthenticatedIdentityProvider(reference below) in both Android and iOS.
May I know how can I get credential information by using token and identity id from amazon-cognito-identity-dart-2?
I am looking forward to your supporting soon.
Thanks in advance!
Reference:
https://docs.aws.amazon.com/cognito/latest/developerguide/developer-authenticated-identities.html
For non federated user pool, this should be a problem.
Cheers
Hi,
I have cloned the example app and I have added awsconfiguration.json file with my cognito info.
I then tried using sign up (i.e. email + password) and this worked, and my user was shown in my user pool.
I then added in google_sign_in package:
google_sign_in: ^4.2.0
And did the necessary config.
I ended up using the code below:
signInGoogle() async { final dynamic result = await signInWithGoogle(); Cognito .federatedSignIn('accounts.google.com', result.idToken) .then((res) { print(res); }).catchError((dynamic error) { print(error); }); }
I get a "flutter: UserState.SIGNED_IN" back and the state shows that I'm signed in.
I then go under my groups, e.g.
Groups => eu-west-xxx_Google
But I don't see the user.
I don't have any errors in the app, and so was wondering if you could point me in the right direction to get this working.
Thanks, Robert
SignedRequests have still a Content-Type Header even if its a GET method.
sig_v4.dart:
As first the Header is set to application/json as its default.
if (headers['Content-Type'] == null) {
headers['Content-Type'] = awsSigV4Client.defaultContentType;
}
This If would remove the Header, if the Body is ''
if (body == '') {
headers.remove('Content-Type');
}
As as next the _generateAuthorization is triggered, which builds the Canonical Request and the Authorization Header. So if body is '', the Header is removed and the request is without correct headers, because as last, there is an additional IF which would add the Header if null.
if (headers['Content-Type'] == null) {
print("8");
headers['Content-Type'] = awsSigV4Client.defaultContentType;
}
Important is, that the Content-Type will never be removed. This is not a real problem if you work with the http package , because it simply sends the content-type with the request and therefore the SigV4 request is valid.
But there is a problem with dio, because it removes the content-type header from GET requests, because there is no content.
I found a working Solution for now:
// Add the Content Type only if method is not GET
if (headers['Content-Type'] == null **&& this.method != 'GET'**) {
headers['Content-Type'] = awsSigV4Client.defaultContentType;
}
Also removed following Code at the end of Constructor.
if (headers['Content-Type'] == null) {
print("setting");
headers['Content-Type'] = awsSigV4Client.defaultContentType;
}
Your example shows using cognito. is it difficult to change this to use accesskeyid and secret? I managed to get S3 upload working (code below) but for GET's (and DELETE's) which don't have request body's but instead rely on header values, i have had no luck.
Future<Map> send(
{@required String imagePathOfPhone,
@required String imagePathInS3Bucket,
@required String bucketName,
@required String accessKeyId,
@required String secretKeyId,
@required String region,
@required String s3Endpoint}) async {
final file = File(imagePathOfPhone);
final stream = http.ByteStream(DelegatingStream.typed(file.openRead()));
final length = await file.length();
final uri = Uri.parse(s3Endpoint);
final req = http.MultipartRequest("POST", uri);
final multipartFile = http.MultipartFile('file', stream, length,
filename: path.basename(file.path));
final policy = Policy.fromS3PreSignedPost(
imagePathInS3Bucket, bucketName, accessKeyId, 15, length,
region: region);
final key =
SigV4.calculateSigningKey(secretKeyId, policy.datetime, region, 's3');
final signature = SigV4.calculateSignature(key, policy.encode());
req.files.add(multipartFile);
req.fields['key'] = policy.key;
req.fields['acl'] = 'public-read';
req.fields['X-Amz-Credential'] = policy.credential;
req.fields['X-Amz-Algorithm'] = 'AWS4-HMAC-SHA256';
req.fields['X-Amz-Date'] = policy.datetime;
req.fields['Policy'] = policy.encode();
req.fields['X-Amz-Signature'] = signature;
try {
final res = await req.send();
[...]
Any chance you can point me in the right direction?
x-amz-security-token:${_credentials.sessionToken}
_credentials.secretAccessKey
are the two fields i can't figure out doing the non-cognito way.
Any help is much appreciated.
When I am using GET the request succeeds.
But when I use POST with a body I get this error response, POST without a body can work
The request signature we calculated does not match the signature you provided. ...
I saw someone mentioned exactly the same issue in amazon-cognito-idenity-dart: jonsaw/amazon-cognito-identity-dart#35
But I tried following code without any luck, any help is appreciated!
final headers = Map<String, String>();
headers["Content-Type"] = "application/json; charset=utf-8";
final signedRequest = SigV4Request(client, method: 'POST', path: path, body: jsonBody, headers: headers);
final response = await http.post(signedRequest.url, headers: signedRequest.headers, body: jsonBody);
Hi, i'm your using your library to develop my application that connects to cognito.
Phases of registration and login fuction correctly but i have problems in undertanding few things.
First of all, how keep my user loggend after his first login?
I red the example code but i don't understand what the init fuctions really does or better, I understand what i does but i don't understand how should I use it and the absence of the docs hits really hard.
Can you gently help me explaining the sequence of how should i can keep my user logged?
When sending a code for SMS MFA an error is thrown of CognitoUserException: User Confirmation Necessary although the user is already of status confirmed
ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: CognitoUserException: User Confirmation Necessary
E/flutter (13388): #0 CognitoUser.sendMFACode (package:amazon_cognito_identity_dart_2/src/cognito_user.dart:871:7)
I am sending the SMS MFA code that the user receives after they attempt to login. This is automatically sent cause MFA is required on the pool.
Hello,
I need some help with v4 signature.
I am generating pre signed url using generate_presigned_post call - https://boto3.amazonaws.com/v1/documentation/api/latest/guide/s3-presigned-urls.html
This comes with a output like this:
{'url': 'https://mybucket.s3.amazonaws.com
'fields': {'acl': 'public-read',
'key': 'mykey', 'signature': 'mysignature', 'policy': 'mybase64 encoded policy'}
}
Here is my dart code
File vfile=File(filepath);
var stream = new http.ByteStream(DelegatingStream.typed(vfile.openRead()));
var length = await vfile.length();
var uri = Uri.parse(signed_url['url']);
var request = new http.MultipartRequest("POST", uri);
String _secretKeyId = signed_url['fields']['signature'];
String accessKeyId = signed_url['fields']['accessKeyId'];
String sessionToken = signed_url['fields']['policy'];
const _region = 'ap-south-1';
String _s3Endpoint = signed_url['url'];
String _policy=signed_url['fields']['policy'];
dynamic policy_json=jsonDecode(utf8.decode(base64.decode(_policy)));
final multipartFile = http.MultipartFile('file', stream, length,
filename: path.basename(vfile.path));
final presigned_policy = Policy.fromS3PresignedPost(
'square-cinnamon.mp4',
'my-s3-bucket',
accessKeyId,
15,
length,
region: _region);
final key = SigV4.calculateSigningKey(
_secretKeyId, presigned_policy.datetime, _region, 's3');
final signature = SigV4.calculateSignature(key, presigned_policy.encode());
final req = http.MultipartRequest("POST", uri);
req.files.add(multipartFile);
req.fields['key'] = presigned_policy.key;
req.fields['acl'] = 'public-read';
req.fields['X-Amz-Credential'] = presigned_policy.credential;
req.fields['X-Amz-Algorithm'] = 'AWS4-HMAC-SHA256';
req.fields['X-Amz-Date'] = presigned_policy.datetime;
req.fields['Policy'] = presigned_policy.encode();
req.fields['X-Amz-Signature'] = signature;
req.fields['x-amz-security-token'] = "null"; // As we dont get this via generate_presigned_port call
try {
final res = await req.send();
await for (var value in res.stream.transform(utf8.decoder)) {
print(value);
}
} catch (e) {
print("***** Exception in sending file *****" + e.toString());
}
I get a error
<Error><Code>InvalidAccessKeyId</Code><Message>The AWS Access Key Id you provided does not exist in our records.</Message><AWSAccessKeyId>null</AWSAccessKeyId><RequestId>C7315716981A0E20</RequestId><HostId>R/Xkg4evb/oZR1EleAm+zHahUb5R9fFjL+wv5mcENwTG1EB95o0A5KojKq2RdhJyhHkLyxrrNFA=</HostId></Error>
Appreciate a response.
Thanks,
Shekar
I created a cognito user pool according to those instructions. I have done this numerous times.
Yesterday, I was able to register. Today, I tried to login but the login screen would not render and then when I recreated the user pool I get this error for the username failing a regular expression pattern.
As the title suggest, I need to develop an app with huge userbase but we need to use AWS. Is it possible to upload and get videos with this package?
The following snippet from the package README does not work as expected
CognitoUserSession session;
try {
session = await cognitoUser.authenticateUser(authDetails);
...
} on CognitoUserConfirmationNecessaryException catch (e) {
// handle User Confirmation Necessary
} on CognitoClientException catch (e) {
// handle Wrong Username and Password and Cognito Client
}
...
When using this code CognitoUserConfirmationNecessaryException is not thrown. Rather:
CognitoClientException{statusCode: 400, code: UserNotConfirmedException, name: UserNotConfirmedException, message: User is not confirmed.}
Expected Behavior: Correct exception should be thrown so the client can handle the challenge appropriately.
How can I get the group or grups a user belongs to
While trying "use case4" it is not quite clear how to handle the sending of a TOTP code after login to authenticate. Please provide a solution. Thanks :)
I notice this takes another package and adds a '2' to the end of its' name and is a fork of that package. I assume that you needed the original package and that it was no longer supported by the original developer, so you started building on top of it?
I ask because I need this package but it looks strange and I want something that will be supported (not asking for new features).
Hi,
i try to query a API GW with your plugin, but when i insert an umlaut like 'ä,ö,ü' its not working correctly and ive got the error:
"{message: The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details."
Without Umalute its working quite well.
Request i sent
GET
/path/%C3%A4
accept:application/json
content-type:application/json
host:yyyyyyy.execute-api.eu-central-1.amazonaws.com
x-amz-date:20191229T163450Z
Exception:
{message: The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.
'GET
/path/%25C3%25A4
accept:application/json
content-type:application/json
host:yyyyyyy.execute-api.eu-central-1.amazonaws.com
x-amz-date:20191229T163450Z
}
Hi, I am trying to integrate aws with firebase as an identity provider. On flutter side I am using the firebase_auth package with the following code:
FirebaseUser user = await FirebaseAuth.instance.currentUser();
String fb_token;
user.getIdToken().then((result) {
fb_token = result.token;
});
Now I am trying to connect to aws via an Identity pool. I am following the approach outlined in this SO post: https://stackoverflow.com/questions/47228334/firebase-as-identity-provider-with-cognito-aws/47252192
But so far I haven't had any luck finding a dart package that would support connecting to cognito with openId and identity pools. Do you have any suggestions on how to solve this problem or am I perhaps missing something?
Many thanks!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.