Flutter google sign in serverAuthCode - flutter

I'm using this flutter plugin google_sign_in 5.2.1
works good I get the response
{displayName: Mario Mc, email: myemail#gmail.com, id: 117816213074325689769, photoUrl: https://lh3.googleusercontent.com/a-/AOh14GgyaPy7ik693hjyIBmtW5IRXUdCXluaeI=s96-c, serverAuthCode: 4/0AX4XfWiqJ1DMfPaDbgf6gOFVMCfgMicyPqGk25bxjKfA4wq7bJCCu-TWRB8c3rAz_g}
My question is: what is serverAuthCode?
And what's id: 117816213074325689769 used for
And after I send that serverAuthCode to the server, how do I verify that code is legit by calling google servers(as you know any person can send a fake serverAuthCode, so we need to verify it before saving it or do something with it)
I want to use PHP in the server side
thanks

What you can do is use this to get the accessToken then send it to the server
// sign In With Google
_googleSignIn.signIn().then((userData) {
userData.authentication.then((googleKey) {
setState(() {
// Retrieve the email from Google auth
googleEmail = userData.email;
googleId = userData.id;
googlePhotoUrl = userData.photoUrl;
googleServerAuthCode = userData.serverAuthCode;
googleAccessToken = googleKey.accessToken;
googleIdToken = googleKey.idToken;
});
print("googleAccessToken");
print(googleAccessToken);
// call your login function if no errors
checkInternetAndLoginWithGoogle();
}).catchError((err) {
print('inner error');
});
}).catchError((err) {
print('error occurred');
print(err);
});
in the server side, you can verify that access token by calling
https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=<access token>
you will get an answer if that token is valid or expired
Also, you can call this to get user info such as name, email, photo etc.
https://www.googleapis.com/oauth2/v3/userinfo?access_token=<access token>

Related

How to logout with openid_client after authentication via pkce in flutter app with keycloak using openid_client?

I have the following KeyCloak Client config, to use pkce authentication flow:
Realm: REALM
Client ID: pkce-client
Client Protocol: openid-connect
Access Type: public
Standard Flow Enabled: ON
Valid Redirect URIs: http://localhost:4200/
Advanced Settings:
Proof Key for Code Exchange Code Challenge Method: S256
After authenticating with flutter App with iOS Simulator via openid_client
https://pub.dev/packages/openid_client at some point I need to log out.
I can do this to get the logout URL:
String localhost = getLocalhost();
var uri = Uri.parse('http://$localhost:8180/auth/realms/REALM');
var clientId = 'pkce-client';
var issuer = await Issuer.discover(uri);
var client = Client(issuer, clientId);
String idT = token.idToken.toCompactSerialization();
Credential credential = client.createCredential(
tokenType: token.tokenType,
refreshToken: token.refreshToken,
idToken: idT,
);
var url;
try {
url = credential.generateLogoutUrl();
} catch (e) {
print("Error during login (refresh) " + e.toString());
}
urlLauncher(String url) async {
if (await canLaunch(url)) {
await launch(url, forceWebView: true);
} else {
throw 'Could not launch $url';
}
}
String callUrl = url.toString();
urlLauncher.call(callUrl);
This is how the logout url looks like:
http://localhost:8180/auth/realms/vopi/protocol/openid-connect/logout?id_token_hint=eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICIxUVJwMXAtbmk1WmcyZmlyRHFoRS1iS1hwe.......
I'm not logged out after calling the url. Can someone help with this?
Thanks in advance
Redirect browser (web view) to that logout url (logout URL is not an API call, so you can't use XMLHttpRequest). That terminates existing IdP session. Of course you need to destroy also any local tokens (access/id/refresh token), which your app already has.
the IDP should have a front end logout url that you can call to logout of the current session. it is a call directly from the browser to the IDP endpoint.
the IDP front end logout should terminate the session, clear any cookies but the backend tokens (access token , refresh token etc) need to be cleared by your application.

How to fetch page list from Facebook Graph API?

I can download user events but not user managed pages. Why? What is the difference?
Using react-facebook-login to get user access token
import FacebookLogin from "react-facebook-login";
Adding Facebook login to the screen, it has the pages_show_list permission:
<FacebookLogin
appId={fbAppId}
autoLoad={true}
fields="name,email,picture"
scope="public_profile,pages_show_list"
onClick={this.componentClicked}
callback={this.responseFacebook}
And here is the handler:
responseFacebook = response => {
this.setState({
accessToken: response.accessToken,
isLoggedIn: true,
userID: response.userID,
name: response.name,
email: response.email,
picture: response.picture.data.url
});
axios.get('https://graph.facebook.com/v5.0/me/accounts&access_token='+response.accessToken)
.then(response => {
console.log("aaa " + response);
console.log("bbb ");
})
};
Second breakpoint will not be reached.
But get a lot of strange error:
Facebook API Explorer returns the data
Code is here: https://gitlab.com/j4nos/ticket-portal/blob/master/src/App.js
But get a lot oof strange error:
Focus.
The main part of importance here is that it shows that you are getting a 400 Bad Request response from the API, with that URL you tried to request there.
https://graph.facebook.com/v5.0/me/accounts&access_token=...
How does the query string portion of a URL start again ...?
Question mark, not ampersand.

google-api-nodejs-client: how to call google+ domain api locally? (by the plusDomains.media.insert)

I am going to use the Nodejs google api client(google-api-nodejs-client) to post a photo to my google+. (I have listed all my code at end of this post.)
Let me introduce a little bit background:
I have created a project on: console.developers.google.com
I have enabled google+ domain API for this project.
I have created credentials for this project as well. (it is a OAuth 2.0 client ID)
I have a little bit experience of using the client (google-api-nodejs-client) and I can post images and files to my google drive by it.
However, posting to google+ photo is different, the auth is the key different. I have tried several different ways, but none of them works.
The api always return me this:
{ [Error: Forbidden]
code: 403,
errors: [ { domain: 'global', reason: 'forbidden', message: 'Forbidden' } ] }
I also found this:
Warning: The Google+ Sign-In button and the plus.login scope used by
Google+ Sign-In, are not currently supported for use with the Google+
Domains API. Requests that are made to the Google+ Domains API using
an authentication token granted for the
www.googleapis.com/auth/plus.login scope, or generated by the
Google+ Sign-In button, will fail.
If it doesn't support the sign-button, what does it support?
This page tell me to add a domain delegation (https://developers.google.com/+/domains/authentication/delegation), but i haven't push my program into any server, i just try to run it locally.
I was wondering if it is possible to use this client to post photo to google+ by run a nodejs program locally?
var CLIENT_ID = "xxxxxxx.apps.googleusercontent.com";
var CLIENT_SECRET = "xxxxxxxx";
var REDIRECT_URL = "https://xxxxxxx";
var readline = require('readline');
var async = require('async');
var google = require('googleapis');
var request = require('request');
var OAuth2 = google.auth.OAuth2;
var oauth2Client = new OAuth2(CLIENT_ID, CLIENT_SECRET, REDIRECT_URL);
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
function getAccessToken (oauth2Client, callback) {
// generate consent page url
var scopes = [
'https://www.googleapis.com/auth/plus.me',
'https://www.googleapis.com/auth/plus.stream.read',
'https://www.googleapis.com/auth/plus.stream.write',
'https://www.googleapis.com/auth/plus.circles.read',
'https://www.googleapis.com/auth/plus.circles.write',
'https://www.googleapis.com/auth/plus.media.upload'
];
var url = oauth2Client.generateAuthUrl({
access_type: 'offline', // 'online' (default) or 'offline' (gets refresh_token)
scope: scopes, // If you only need one scope you can pass it as string,
key: 'p7UALH460Deqodhvb2zESYya'
});
console.log('Visit the url: ', url);
rl.question('Enter the code here:', function (code) {
// request access token
oauth2Client.getToken(code, function (err, tokens) {
if (err) {
return callback(err);
}
// set tokens to the client
// TODO: tokens should be set by OAuth2 client.
oauth2Client.setCredentials(tokens);
console.dir(tokens);
callback();
});
});
}
getAccessToken(oauth2Client, function () {
var plusDomains = google.plusDomains({ version: 'v1', auth: oauth2Client });
var requestObj = request({url:'http://asset1.cxnmarksandspencer.com/is/image/mands/2643f540b32fe8c6cccdec95b3a2c5239166232f?$editorial_430x430$'});
const Readable = require('stream').Readable;
var iamgeStream = new Readable().wrap(requestObj);
plusDomains.media.insert({
userId: 'me',
collection: 'cloud',
resource: {
name: 'testimage.png',
mimeType: 'image/png'
},
media: {
mimeType: 'image/png',
body: iamgeStream
},
access:{domainRestricted :"true"}
}, callbackFn);
function callbackFn(argument) {
console.dir(argument);
}
});
Thanks you very much!
Peter

Meteor Facebook login (Meteor.loginWithFacebook) issue extracting public profile, email and user_friends

Trying to get Meteor Facebook login to work. It functions fully in that it uses Facebook API and requests the correct permissions from the users account and then logs in successfully.
The problem is it doesn't save the permission requested information even though its been approved and only the basic name and ID are available in Meteor.user().services.facebook. Is this code not working because it's not saving the users details on login? I can't find a resource that details how to save or extract the other data.
Simply trying to console log the data to see that it's been extracted out of the Facebook user account on log in.
Within Meteor.isClient code:
Template.login.events({
'click #facebook-login': function(event) {
Meteor.loginWithFacebook({ requestPermissions: ['email', 'public_profile', 'user_friends', 'user_likes']}, function(err){
if (err) {
throw new Meteor.Error("Facebook login failed");
}
console.log(Meteor.user().services.facebook.name);
console.log(Meteor.user().services.facebook.id);
console.log(Meteor.user().services.facebook.email);
console.log(Meteor.user().services.facebook.gender);
});
},
'click #logout': function(event) {
Meteor.logout(function(err){
if (err) {
throw new Meteor.Error("Logout failed");
}
});
}
The config code:
ServiceConfiguration.configurations.remove({
service: 'facebook'
});
ServiceConfiguration.configurations.insert({
service: 'facebook',
appId: 'correctAppID',
secret: 'CorrectSecret'
});
For Facebook v2.4 API after you have requested for certain permissions you can then access them by making a graph API call and requesting them with a valid auth token. The code is as follows:
if (user.hasOwnProperty('services') && user.services.hasOwnProperty('facebook') ) {
var result = Meteor.http.get('https://graph.facebook.com/v2.4/' + user.services.facebook.id + '?access_token=' + user.services.facebook.accessToken + '&fields=first_name, last_name, birthday, email, gender, location, link, friends');
console.log(result.data.first_name);
console.log(result.data.last_name);
console.log(result.data.birthday);
console.log(result.data.email);
console.log(result.data.gender);
console.log(result.data.location);
console.log(result.data.link);
console.log(result.data.friends);
}

Error 500 backendError with Gmail API and Google APIs Node Client

I'm trying to use the new Gmail API with the Google API Node client. I created a new project from the developer console, set up a new "Service Account" Client ID, and enabled access to the API.
As a proof of concept, I am simply trying to list the threads in my inbox. When I enable the OAuth 2.0 toggle for the API explorer and enter my email address, the request succeeds and I see a JSON response with data.
Now I try to do the same in Node:
var googleapis = require('googleapis');
var SERVICE_ACCOUNT_EMAIL = '...SNIP...';
// generated by: openssl pkcs12 -in ...SNIP...p12 -out key.pem -nocerts -nodes
var SERVICE_ACCOUNT_KEY_FILE = 'key.pem';
var jwt = new googleapis.auth.JWT(
SERVICE_ACCOUNT_EMAIL,
SERVICE_ACCOUNT_KEY_FILE,
null,
['https://www.googleapis.com/auth/gmail.readonly']);
googleapis
.discover('gmail', 'v1')
.execute(function(err, client) {
jwt.authorize(function(err, result) {
if(err) console.error(err);
else console.log(result);
client.gmail.users.threads.list()
.withAuthClient(jwt)
.execute(function(err, result) {
if(err) console.error(err);
else console.log(result);
});
});
});
First I print the results of the authorize() call, which looks like it returns a token, so I think I have all the OAuth stuff setup properly:
{ access_token: '...SNIP...',
token_type: 'Bearer',
expires_in: 1404277946,
refresh_token: 'jwt-placeholder' }
Then I try to actually use the API, but I get an error:
{ errors:
[ { domain: 'global',
reason: 'backendError',
message: 'Backend Error' } ],
code: 500,
message: 'Backend Error' }
At this point, I don't know what else to try. I think the OAuth stuff is working properly, because I haven't gotten any authentication errors. I also think the API itself is working and my account is fine, because I can use it through the API Explorer. I don't see any indication that the Node library is at fault either. In short, I have no idea what the problem is. Any ideas?
You are using the Service Account to authenticate your requests to GMail. Your Service Account will not have a Gmail as far as I know, only users have GMail. For this reason you will need to do the OAuth2 flow with the user (see here for example).