Closed idkjs closed 5 years ago
Hi, Same issue here. Any updates?
When I use a http GET and pass the Authentication header, the Api respond normally. But when I use the AwsSigV4Client, the "Unable to parse JWT token." error appears.
Best Regards
@idkjs @roger1345
So, I'm not using lambda or any other aws services at the moment, but I am using cognito and verifying the jwt token in my own backend server (at the moment).
I'm getting the jwt token without producing my own. I'm not sure if this will work for you all, but I'm sharing in case it does:
_user.getSession().getAccessToken().getJwtToken()
This provides me with the JWT token I need on the backend because I supply that through the authorization
header like so:
headers['Authorization'] = 'Bearer ' + token;
As I understand it, if you're using a lambda function through apigateway you can do the same thing using an authorization header and the lambda will process that as a jwt token. Again, I mention gateway because I suspect that is what appsync is using, but maybe not. Either way, maybe it'll help you figure something else out?
Hope it helps.
Depending on your Authorization Type
You will need to sign the request:
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 {
const _awsUserPoolId = 'ap-southeast-1_xxxxxxxxx';
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 _endpoint =
'https://xxxxxxxxxxxxxxxxxxxxxxxxxx.appsync-api.ap-southeast-1.amazonaws.com';
final sigV4Client = AwsSigV4Client(
_credentials.accessKeyId,
_credentials.secretAccessKey,
_endpoint,
serviceName: 'appsync',
sessionToken: _credentials.sessionToken,
region: 'ap-southeast-1',
);
final query = '''mutation CreateItem {
createItem(name: "Some Name") {
name
}
}''';
final _signedRequest =
SigV4Request(sigV4Client, method: 'POST', path: '/graphql', headers: {
'Content-Type': 'application/graphql; charset=utf-8',
}, body: {
'operationName': 'CreateItem',
'query': query,
});
print(_signedRequest.headers);
http.Response response;
try {
response = await http.post(_signedRequest.url,
headers: _signedRequest.headers, body: _signedRequest.body);
} catch (e) {
print(e);
}
print(response.body);
}
A simple Authorization
with JWT token will do.
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:amazon_cognito_identity_dart/cognito.dart';
void main() async {
const _awsUserPoolId = 'ap-southeast-1_xxxxxxxxx';
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 _endpoint =
'https://xxxxxxxxxxxxxxxxxxxxxxxxxx.appsync-api.ap-southeast-1.amazonaws.com';
final body = {
'operationName': 'CreateProfile',
'query': '''mutation CreateItem {
createItem(name: "Some Name") {
name
}
}''',
};
http.Response response;
try {
response = await http.post(
'$_endpoint/graphql',
headers: {
'Authorization': _session.getAccessToken().getJwtToken(),
'Content-Type': 'application/json',
},
body: json.encode(body),
);
} catch (e) {
print(e);
}
print(response.body);
}
Hi @jonsaw ,
This is great and it is worked for me.
I have doubt I have a flutter application and I need login only some areas. Remain area how I fetch data from appSync using unauthenticated.
and we hardcoding user name and password with in the app is not good, right?
Please help me on this.
@jonsaw great demo. Thanks for sharing.
I'm trying to call APPSYNC using this package in the example project. I'm guided by the example Appsync use case in @ncb000gt pull request.
Below is the
UserService
method in theUserService
class modified. It throws the following error when I run it.In javascript aws-sdk the params we have to pass are: https://github.com/dabit3/appsync-react-native-with-user-authorization/blob/b312924fe57e0936186b4688d7c856b13e76c27b/App.js#L30-L37
I'm thinking that solution is to pass
AMAZON_COGNITO_USER_POOLS
toawsSigV4Client
some way. Any ideas on how to do this correctly?Thank you.