0 purchases
amazon cognito identity dart
Amazon Cognito Identity SDK for Dart #
Unofficial Amazon Cognito Identity SDK written in Dart for Dart.
Based on amazon-cognito-identity-js.
Need ideas to get started?
Check out use cases below.
Example Flutter app can be found here.
Authenticated access to:
AppSync + GraphQL found here.
API Gateway + Lambda found here.
S3 Presigned Post found here.
S3 GET Object with Authorization found here.
Follow the tutorial on Serverless Stack for best Cognito setup.
Please note that this package is not production ready.
Usage #
Use Case 1. Registering a user with the application. One needs to create a CognitoUserPool object by providing a UserPoolId and a ClientId and signing up by using a username, password, attribute list, and validation data.
import 'package:amazon_cognito_identity_dart/cognito.dart';
final userPool = new CognitoUserPool(
'ap-southeast-1_xxxxxxxxx', 'xxxxxxxxxxxxxxxxxxxxxxxxxx');
final userAttributes = [
new AttributeArg(name: 'first_name', value: 'Jimmy'),
new AttributeArg(name: 'last_name', value: 'Wong'),
];
var data;
try {
data = await userPool.signUp('[email protected]', 'Password001',
userAttributes: userAttributes);
} catch (e) {
print(e);
}
copied to clipboard
Use case 2. Confirming a registered, unauthenticated user using a confirmation code received via SMS/email.
import 'package:amazon_cognito_identity_dart/cognito.dart';
final userPool = new CognitoUserPool(
'ap-southeast-1_xxxxxxxxx', 'xxxxxxxxxxxxxxxxxxxxxxxxxx');
final cognitoUser = new CognitoUser(
'[email protected]', userPool);
bool registrationConfirmed = false;
try {
registrationConfirmed = await cognitoUser.confirmRegistration('123456');
} catch (e) {
print(e);
}
print(registrationConfirmed);
copied to clipboard
Use case 3. Resending a confirmation code via SMS/email for confirming registration for unauthenticated users.
import 'package:amazon_cognito_identity_dart/cognito.dart';
final userPool = new CognitoUserPool(
'ap-southeast-1_xxxxxxxxx', 'xxxxxxxxxxxxxxxxxxxxxxxxxx');
final cognitoUser = new CognitoUser(
'[email protected]', userPool);
final String status;
try {
status = await cognitoUser.resendConfirmationCode();
} catch (e) {
print(e);
}
copied to clipboard
Use case 4. Authenticating a user and establishing a user session with the Amazon Cognito Identity service.
import 'package:amazon_cognito_identity_dart/cognito.dart';
final userPool = new CognitoUserPool(
'ap-southeast-1_xxxxxxxxx', 'xxxxxxxxxxxxxxxxxxxxxxxxxx');
final cognitoUser = new CognitoUser(
'[email protected]', userPool);
final authDetails = new AuthenticationDetails(
username: '[email protected]', password: 'Password001');
CognitoUserSession session;
try {
session = await cognitoUser.authenticateUser(authDetails);
} on CognitoUserNewPasswordRequiredException catch (e) {
// handle New Password challenge
} on CognitoUserMfaRequiredException catch (e) {
// handle SMS_MFA challenge
} on CognitoUserSelectMfaTypeException catch (e) {
// handle SELECT_MFA_TYPE challenge
} on CognitoUserMfaSetupException catch (e) {
// handle MFA_SETUP challenge
} on CognitoUserTotpRequiredException catch (e) {
// handle SOFTWARE_TOKEN_MFA challenge
} on CognitoUserCustomChallengeException catch (e) {
// handle CUSTOM_CHALLENGE challenge
} on CognitoUserConfirmationNecessaryException catch (e) {
// handle User Confirmation Necessary
} catch (e) {
print(e);
}
print(session.getAccessToken().getJwtToken());
copied to clipboard
Use case 5. Retrieve user attributes for authenticated users.
List<CognitoUserAttribute> attributes;
try {
attributes = await cognitoUser.getUserAttributes();
} catch (e) {
print(e);
}
attributes.forEach((attribute) {
print('attribute ${attribute.getName()} has value ${attribute.getValue()}');
});
copied to clipboard
Use case 6. Verify user attribute for an authenticated user.
var data;
try {
data = await cognitoUser.getAttributeVerificationCode('email');
} catch {
print(e);
}
print(data);
// obtain verification code...
bool attributeVerified = false;
try {
attributeVerified = await cognitoUser.verifyAttribute(
'email', '123456');
} catch (e) {
print(e);
}
print(attributeVerified);
copied to clipboard
Use case 7. Delete user attributes for authenticated users.
try {
final List<String> attributeList = ['nickname'];
cognitoUser.deleteAttributes(attributeList);
} catch (e) {
print(e);
}
copied to clipboard
Use case 8. Update user attributes for authenticated users.
final List<CognitoUserAttribute> attributes = [];
attributes.add(new CognitoUserAttribute(name: 'nickname', value: 'joe'));
try {
await cognitoUser.updateAttributes(attributes);
} catch (e) {
print(e);
}
copied to clipboard
Use case 9. Enabling MFA for a user on a pool that has an optional MFA setting for authenticated users.
bool mfaEnabled = false;
try {
mfaEnabled = await cognitoUser.enableMfa();
} catch (e) {
print(e);
}
print(mfaEnabled);
copied to clipboard
Use case 10. Disabling MFA for a user on a pool that has an optional MFA setting for authenticated users.
bool mfaDisabled = false;
try {
mfaDisabled = await cognitoUser.disableMfa();
} catch (e) {
print(e);
}
print(mfaDisabled);
copied to clipboard
Use case 11. Changing the current password for authenticated users.
bool passwordChanged = false;
try {
passwordChanged = await cognitoUser.changePassword(
'oldPassword', 'newPassword');
} catch (e) {
print(e);
}
print(passwordChanged);
copied to clipboard
Use case 12. Starting and completing a forgot password flow for an unauthenticated user.
import 'package:amazon_cognito_identity_dart/cognito.dart';
final userPool = new CognitoUserPool(
'ap-southeast-1_xxxxxxxxx', 'xxxxxxxxxxxxxxxxxxxxxxxxxx');
final cognitoUser = new CognitoUser(
'[email protected]', userPool);
var data;
try {
data = await cognitoUser.forgotPassword();
} catch (e) {
print(e);
}
print('Code sent to $data');
// prompt user for verification input...
bool passwordConfirmed = false;
try {
passwordConfirmed = await cognitoUser.confirmPassword(
'123456', 'newPassword');
} catch (e) {
print(e);
}
print(passwordConfirmed);
copied to clipboard
Use case 13. Deleting authenticated users.
bool userDeleted = false
try {
userDeleted = await cognitoUser.deleteUser();
} catch (e) {
print(e);
}
print(userDeleted);
copied to clipboard
Use case 14. Signing out from the application.
await cognitoUser.signOut();
copied to clipboard
Use case 15. Global signout for authenticated users (invalidates all issued tokens).
await cognitoUser.globalSignOut();
copied to clipboard
Addtional Features #
Get AWS Credentials #
Get a authenticated user's AWS Credentials. Use with other signing processes like Signature Version 4.
import 'package:amazon_cognito_identity_dart/cognito.dart';
final userPool = new CognitoUserPool(
'ap-southeast-1_xxxxxxxxx', 'xxxxxxxxxxxxxxxxxxxxxxxxxx');
final cognitoUser = new CognitoUser(
'[email protected]', userPool);
final authDetails = new AuthenticationDetails(
username: '[email protected]', password: 'Password001'
);
final session = await cognitoUser.authenticateUser(authDetails);
final credentials = new CognitoCredentials(
'ap-southeast-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', userPool);
await credentials.getAwsCredentials(session.getIdToken().getJwtToken());
print(credentials.accessKeyId);
print(credentials.secretAccessKey);
print(credentials.sessionToken);
copied to clipboard
Signing Requests #
For S3 Uploads
S3 Uploads using HTTP Presigned Post.
import 'dart:convert';
import 'dart:io';
import 'package:path/path.dart' as path;
import 'package:async/async.dart';
import 'package:http/http.dart' as http;
import 'package:amazon_cognito_identity_dart/cognito.dart';
import 'package:amazon_cognito_identity_dart/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-east-1'});
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() {
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}" }
]
}
''';
}
}
void main() async {
const _awsUserPoolId = 'ap-southeast-xxxxxxxxxxx';
const _awsClientId = 'xxxxxxxxxxxxxxxxxxxxxxxxxx';
const _identityPoolId =
'ap-southeast-1:xxxxxxxxx-xxxx-xxxx-xxxxxxxxxxx';
final _userPool = CognitoUserPool(_awsUserPoolId, _awsClientId);
final _cognitoUser = CognitoUser('+60100000000', _userPool);
final authDetails =
AuthenticationDetails(username: '+60100000000', password: 'p&ssW0RD');
CognitoUserSession _session;
try {
_session = await _cognitoUser.authenticateUser(authDetails);
} catch (e) {
print(e);
}
final _credentials = CognitoCredentials(_identityPoolId, _userPool);
await _credentials.getAwsCredentials(_session.getIdToken().getJwtToken());
const _region = 'ap-southeast-1';
const _s3Endpoint =
'https://my-s3-bucket.s3-ap-southeast-1.amazonaws.com';
final file = File(path.join('/path/to/my/folder', 'square-cinnamon.jpg'));
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(
'test/square-cinnamon.jpg',
'my-s3-bucket',
15,
_credentials.accessKeyId,
length,
_credentials.sessionToken,
region: _region);
final key = SigV4.calculateSigningKey(
_credentials.secretAccessKey, 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;
req.fields['x-amz-security-token'] = _credentials.sessionToken;
try {
final res = await req.send();
await for (var value in res.stream.transform(utf8.decoder)) {
print(value);
}
} catch (e) {
print(e.toString());
}
}
copied to clipboard
For S3 GET Object
Signing S3 GET Object using Authorization header.
import 'dart:io';
import 'package:path/path.dart' as path;
import 'package:amazon_cognito_identity_dart/cognito.dart';
import 'package:amazon_cognito_identity_dart/sig_v4.dart';
import 'package:http/http.dart' as http;
void main() {
const _awsUserPoolId = 'ap-southeast-1_xxxxxxxx';
const _awsClientId = 'xxxxxxxxxxxxxxxxxxxxxxxxxx';
const _identityPoolId =
'ap-southeast-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx';
final _userPool = CognitoUserPool(_awsUserPoolId, _awsClientId);
final _cognitoUser = CognitoUser('+60100000000', _userPool);
final authDetails =
AuthenticationDetails(username: '+60100000000', password: 'p@ssW0rd');
CognitoUserSession _session;
try {
_session = await _cognitoUser.authenticateUser(authDetails);
} catch (e) {
print(e);
return;
}
final _credentials = CognitoCredentials(_identityPoolId, _userPool);
await _credentials.getAwsCredentials(_session.getIdToken().getJwtToken());
final host = 's3.ap-southeast-1.amazonaws.com';
final region = 'ap-southeast-1';
final service = 's3';
final key =
'my-s3-bucket/ap-southeast-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/squre-cinnamon.jpg';
final payload = SigV4.hashCanonicalRequest('');
final datetime = SigV4.generateDatetime();
final canonicalRequest = '''GET
${'/$key'.split('/').map((s) => Uri.encodeComponent(s)).join('/')}
host:$host
x-amz-content-sha256:$payload
x-amz-date:$datetime
x-amz-security-token:${_credentials.sessionToken}
host;x-amz-content-sha256;x-amz-date;x-amz-security-token
$payload''';
final credentialScope =
SigV4.buildCredentialScope(datetime, region, service);
final stringToSign = SigV4.buildStringToSign(datetime, credentialScope,
SigV4.hashCanonicalRequest(canonicalRequest));
final signingKey = SigV4.calculateSigningKey(
_credentials.secretAccessKey, datetime, region, service);
final signature = SigV4.calculateSignature(signingKey, stringToSign);
final authorization = [
'AWS4-HMAC-SHA256 Credential=${_credentials.accessKeyId}/$credentialScope',
'SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token',
'Signature=$signature',
].join(',');
final uri = Uri.https(host, key);
http.Response response;
try {
response = await http.get(uri, headers: {
'Authorization': authorization,
'x-amz-content-sha256': payload,
'x-amz-date': datetime,
'x-amz-security-token': _credentials.sessionToken,
});
} catch (e) {
print(e);
return;
}
final file = File(path.join(
'/path/to/my/folder',
'square-cinnamon-downloaded.jpg'));
try {
await file.writeAsBytes(response.bodyBytes);
} catch (e) {
print(e.toString());
return;
}
print('complete!');
}
copied to clipboard
For AppSync's GraphQL
Signing GraphQL requests for authenticated users with IAM Authorization type for access to AppSync data.
import 'package:http/http.dart' as http;
import 'package:amazon_cognito_identity_dart/cognito.dart';
import 'package:amazon_cognito_identity_dart/sig_v4.dart';
void main() async {
final credentials = new CognitoCredentials(
'ap-southeast-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', userPool);
await credentials.getAwsCredentials(session.getIdToken().getJwtToken());
const endpoint =
'https://xxxxxxxxxxxxxxxxxxxxxxxxxx.appsync-api.ap-southeast-1.amazonaws.com';
final awsSigV4Client = new AwsSigV4Client(
credentials.accessKeyId, credentials.secretAccessKey, endpoint,
serviceName: 'appsync',
sessionToken: credentials.sessionToken,
region: 'ap-southeast-1');
final String query = '''query GetEvent {
getEvent(id: "3dcd52c3-1fd6-4e4d-8da6-946ef4a0c94d") {
id
name
comments(limit: 10) {
items {
content
createdAt
}
}
}
}''';
final signedRequest = new SigV4Request(awsSigV4Client,
method: 'POST', path: '/graphql',
headers: new Map<String, String>.from(
{'Content-Type': 'application/graphql; charset=utf-8'}),
body: new Map<String, String>.from({
'operationName': 'GetEvent',
'query': query}));
http.Response response;
try {
response = await http.post(
signedRequest.url,
headers: signedRequest.headers, body: signedRequest.body);
} catch (e) {
print(e);
}
print(response.body);
}
copied to clipboard
For API Gateway & Lambda
Signing requests for authenticated users for access to secured routes to API Gateway and Lambda.
import 'package:http/http.dart' as http;
import 'package:amazon_cognito_identity_dart/cognito.dart';
import 'package:amazon_cognito_identity_dart/sig_v4.dart';
void main() async {
final credentials = new CognitoCredentials(
'ap-southeast-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', userPool);
await credentials.getAwsCredentials(session.getIdToken().getJwtToken());
const endpoint =
'https://xxxx.execute-api.ap-southeast-1.amazonaws.com/dev';
final awsSigV4Client = new AwsSigV4Client(
credentials.accessKeyId, credentials.secretAccessKey, endpoint,
sessionToken: credentials.sessionToken,
region: 'ap-southeast-1');
final signedRequest = new SigV4Request(awsSigV4Client,
method: 'POST',
path: '/projects',
headers: new Map<String, String>.from(
{'header-1': 'one', 'header-2': 'two'}),
queryParams: new Map<String, String>.from({'tracking': 'x123'}),
body: new Map<String, dynamic>.from({'color': 'blue'}));
http.Response response;
try {
response = await http.post(
signedRequest.url,
headers: signedRequest.headers, body: signedRequest.body);
} catch (e) {
print(e);
}
print(response.body);
}
copied to clipboard
Use Custom Storage #
Persist user session using custom storage.
Shared Preferences Plugin storage example found here.
import 'dart:convert';
import 'package:amazon_cognito_identity_dart/cognito.dart';
Map<String, String> _storage = {};
class CustomStorage extends CognitoStorage {
String prefix;
CustomStorage(this.prefix);
@override
Future setItem(String key, value) async {
_storage[prefix+key] = json.encode(value);
return _storage[prefix+key];
}
@override
Future getItem(String key) async {
if (_storage[prefix+key] != null) {
return json.decode(_storage[prefix+key]);
}
return null;
}
@override
Future removeItem(String key) async {
return _storage.remove(prefix+key);
}
@override
Future<void> clear() async {
_storage = {};
}
}
final customStore = new CustomStorage('custom:');
final userPool = new CognitoUserPool(
'ap-southeast-1_xxxxxxxxx', 'xxxxxxxxxxxxxxxxxxxxxxxxxx',
storage: customStore);
final cognitoUser = new CognitoUser(
'[email protected]', userPool,
storage: customStore);
final authDetails = new AuthenticationDetails(
username: '[email protected]', password: 'Password001');
await cognitoUser.authenticateUser(authDetails);
// some time later...
final user = await userPool.getCurrentUser();
final session = await user.getSession();
print(session.isValid());
copied to clipboard
For personal and professional use. You cannot resell or redistribute these repositories in their original state.
There are no reviews.