Tracking Google OAuth2 token changes [duplicate] - javascript

I have a simple single-page javascript webapp which uses "Google Sign-In for Websites": https://developers.google.com/identity/sign-in/web/sign-in
How can I get an access token for the user? I need a verifiable assertion of the user's identity on my server. I don't want offline access; I just want to know that when the web client sends an ajax request to my server, I can trust the identity of the logged-in user.

For verification purposes it would be better to use the id_token which is part of the auth response, and can be retrieved at any point like this:
gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse().id_token
The Google API Client libraries offer functions to verify the id_token and give you the associated user information on the server side: https://developers.google.com/api-client-library/

First, you need to initialize the SDK
Then call the following function to get the access-token
gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse().access_token;
This solution help for me to get access token in javascript.

Hope your are doing well.
Here is the solution, You may try this:
Actually there is no such a function name getAccessToken (Android Only) define in GoogleSignin.android.js as written here https://github.com/devfd/react-native-google-signin.
But the best part is they have already implemented the solution in GoogleSignin.android.js. just take a look at the code below from GoogleSignin.android.js
currentUserAsync() {
return new Promise((resolve, reject) => {
const sucessCb = DeviceEventEmitter.addListener('RNGoogleSignInSilentSuccess', (user) => {
this._user = user;
RNGoogleSignin.getAccessToken(user).then((token) => {
this._user.accessToken = token;
this._removeListeners(sucessCb, errorCb);
resolve(this._user);
})
.catch(err => {
this._removeListeners(sucessCb, errorCb);
resolve(this._user);
});
});
The thing is only we have do use this code wisely.
I have use the below code to get access_token and it help me to solve my access token problem.
I change above function like this in GoogleSignin.android.js
currentUserAsync() {
return new Promise((resolve, reject) => {
const sucessCb = DeviceEventEmitter.addListener('RNGoogleSignInSilentSuccess', (user) => {
this._user = user;
RNGoogleSignin.getAccessToken(user).then((token) => {
this._user.accessToken = token;
this._removeListeners(sucessCb, errorCb);
resolve(token);
})
.catch(err => {
this._removeListeners(sucessCb, errorCb);
resolve(this._user);
});
});
and I call this function like this from index.android.js.
_signIn() {
GoogleSignin.signIn()
.then((user) => {
console.log('this1' + JSON.stringify(user));
this.setState({user: user});
var gettoken = GoogleSignin.currentUserAsync(user).then((token) => {
console.log('USER token', token);
this.setState({user: user});
}).done();
}).catch((err) => {
console.log('WRONG SIGNIN', err);
})
.done();
}
You can call it as a individual function it look like this.
in GoogleSignin.android.js
getAccessTok(user)
{
RNGoogleSignin.getAccessToken(user).then((token) => {
this._user.accessToken = token;
resolve(token);
})
.catch(err => {
this._removeListeners(sucessCb, errorCb);
console.log('got error');
resolve(this._user);
});
}
and from index.android.js just call this function like this
_getToken(){
console.log(GoogleSignin.getAccessTok(this.state.user));
}
only you have to do is to pass the current user to get access token.
Hope this will help you.Have a great day.Thank You.

Yeah, it is 2021. And I was facing the same problem.
My solution is
gapi.signin2.render(this.id, {
scope: this.scope,
width: this._width,
height: this._height,
longtitle: this._longTitle,
theme: this.theme,
// Set to true, otherwise only user actively logging in with Google will have access token
onsuccess: (googleUser: gapi.auth2.GoogleUser) => googleUser.getAuthResponse(true),
onfailure: () => this.handleFailure()
});

Related

Firebase - Why is the claim not added to the user attributes?

I'm adding the claim to a user's profile that he or she paid for something, though, after the payment this attribute isn't visible. I'm running the functions on an emulator on a local host.
This is the code I'm using:
If the paypal function has been handled succesfully through paypalHandleOrder, then the function addPaidClaim is invoked.
onApprove: (data, actions) => {
paypalHandleOrder({ orderId: data.orderID }).then(
addPaidClaim(currentUser).then(
alert("THANKS FOR ORDERING!"),
// currentUser.getIdTokenResult().then(idTokenResult => {
// console.log(idTokenResult.claims)
// })
)
.catch((err) => {
return err;
})
);}
addPaidClaim is a firebase cloud function, which goes as follows:
exports.addPaidClaim = functions.https.onCall((data, context) => {
// get user and add custom claim (paid)
return admin.auth().setCustomUserClaims(data.uid, {
paid: true,
}).then(() => {
return {
message: `Success! ${data.email} has paid the course`,
};
}).catch((err) => {
return err;
});
});
I've refreshed the page and checked the user attributes afterwards through console.log on the user to see if the attribute had been added, but this is not the case. I can't find attribute paid inside the idTokenResult object. What should I do? I also find it hard to make sense of what's happening inside the function addPaidClaim. It's not returning an error when I look at the logs on my firebase console, and not much information is given, besides that the function has been invoked.
Okay, I know this question is pretty old. But I found a way just yesterday after 3 days searching over the solution. After we set up a new claim for a new user using, we need to refresh the client's getIdTokenResult(true) in the app. These are the ways I did it in Flutter Dart until a new user with updated claim managed to use it:
FirebaseAuth auth = FirebaseAuth.instance;
Future<Map<String, dynamic>> signInWithGoogle() async {
Map<String, dynamic> output = {};
final googleUser = await googleSignIn.signIn();
if (googleUser == null) {
log("Firebase => Gmail account doesn't exist");
} else {
final googleAuth = await googleUser.authentication;
final credential = GoogleAuthProvider.credential(
idToken: googleAuth.idToken,
accessToken: googleAuth.accessToken,
);
await auth.signInWithCredential(credential).then((values) async {
await userAuth(credential).then((value) =>
value.addAll(output));
});
}
return output;
}
Future<Map<String, dynamic> userAuth (OAuthCredential credential) async {
Map<String, dynamic> output = {};
await auth.currentUser!.reauthenticateWithCredential(credential);
await auth.currentUser!.reload();
await auth.currentUser!.getIdTokenResult().then((result) => {
if(result.claims!.isNotEmpty){
//check your claim here
} else {
//assign log here
}
});
return output;
}

Send data using react-native-ble-plx package

In order to realize a project of connected objects. I need to implement a Bluetooth connection between the various devices.
Here, the goal is to create an application in React Native and then send data from this application to my Raspberry. This Raspberry has a connected HC-08 module that takes care of Bluetooth communication.
Now, I would like to use react-native-ble-plx library to send data through Bluetooth. I'm able to connect my Android to the module. But I don't understand how to send data ...
Here's my code :
constructor() {
super()
this.manager = new BleManager()
}
componentWillMount() {
console.log("mounted")
const subscription = this.manager.onStateChange((state) => {
if (state === 'PoweredOn') {
this.scanAndConnect();
subscription.remove();
}
}, true);
}
scanAndConnect() {
this.manager.startDeviceScan(null, null, (error, device) => {
if (error) {
// Handle error (scanning will be stopped automatically)
return
}
console.log(device.name)
// Check if it is a device you are looking for based on advertisement data
// or other criteria.
if (device.name === 'SH-HC-08') {
// Stop scanning as it's not necessary if you are scanning for one device.
this.manager.stopDeviceScan();
console.log(`Found ${device.name}`)
this.setState({
device: device
})
// Proceed with connection.
device.connect()
.then((device) => {
console.log(device)
return device.discoverAllServicesAndCharacteristics()
})
.then((device) => {
console.log(device)
})
.then((result) => {
// Do work on device with services and characteristics
//console.log(this.manager.characteristicsForService("00001800-0000-1000-8000-00805f9b34fb"))
console.log(result)
console.log("connected")
})
.catch((error) => {
// Handle errors
console.log(error)
});
}
});
}
send() {
this.manager.writeCharacteristicWithResponseForDevice("58:7A:62:4F:EF:6D",
this.device.serviceUUIDs[0],
this.manager.characteristicsForDevice(this.device.id),
"ok")
.catch((error) => {
console.log('error in writing data');
console.log(error);
})
}
I would like to have a send method that will send data whenever I want to. But I don't really understand how it works :/
Could someone help me or even give me an example ? I would be really appreciated.
Best regards.
I had success implementing the following:
scanAndConnect() {
this.manager.startDeviceScan(null, null, (error, device) => {
this.info("Scanning...");
console.log(device);
if (error) {
this.error(error.message);
return
}
if (device.name ==='MyDevice') {
this.info("Connecting to Tappy");
this.manager.stopDeviceScan();
device.connect()
.then((device) => {
this.info("Discovering services and characteristics");
return device.discoverAllServicesAndCharacteristics()
})
.then((device) => {
this.info(device.id);
device.writeCharacteristicWithResponseForService('12ab', '34cd', 'aGVsbG8gbWlzcyB0YXBweQ==')
.then((characteristic) => {
this.info(characteristic.value);
return
})
})
.catch((error) => {
this.error(error.message)
})
}
});
Where I use 12ab, insert the UUID of your BLE service. Similarly, where I use 34cd, insert the UUID of your BLE characteristic. Lastly, include a base64 encoding of whatever message you're trying to send where I have aGVsbG8gbWlzcyB0YXBweQ==.
Hope this helps.

Firebase - Change displayName for Facebook provider

I'm fairly new to the Firebase ecosystem, so I hope I'm not asking something too basic.
I'm using the firebase-js-sdk along with an e-mail + password registration. When the user signs up using an e-mail I prompt them to select their username and I store it using the user.updateProfile() method. This works fine, as the next time I call firebase.auth().currentUser I see the displayName property containing the updated value.
As for facebook, I'm using the react-native-fbsdk, and I authenticate the user using the following function:
const fbLogin = () => {
return new Promise((resolve, reject) => {
LoginManager
.logInWithReadPermissions(['public_profile', 'email'])
.then((result) => {
if (result.isCancelled) {
console.log('login cancelled');
} else {
AccessToken
.getCurrentAccessToken()
.then((data) => {
const credentials = firebase.auth.FacebookAuthProvider.credential(data.accessToken);
firebase
.auth().signInWithCredential(credentials)
.then((res) => resolve(res))
.catch((err) => reject(err));
})
}
}).catch(err => reject(err));
});
}
Once I store the user's data on Firebase I ask him to choose an username and I update the displayName following the same steps of the e-mail authentication. This seems to work too because if I call firebase.auth().currentUser I see the updated displayName. The only problem is when I reload the app the displayName is back to the facebook name.
My questions are:
Is it possible to override the displayName provided by Facebook?
If so, is this the correct approach to do so?
Thanks in advance to anyone that will help :)

Can not login after npm update Firebase

I updated firebase to "firebase": "^4.2.0". Seems like the user's object properties changed.
const loginGG = () => {
try {
firebase.initializeApp(clientCredentials)
} catch (e) {
console.log('firebase is already created')
}
return firebase.auth().signInWithPopup(new firebase.auth.GoogleAuthProvider())
.then(result => {
if(!result || !result.user) throw new Error('LOGIN ERROR')
const token = result.user.ze;
const user = result.user;
Cookies.set('tapId', token);
Cookies.set('tapUser', JSON.stringify(user));
history.go(-1);
return {
user,
token
}
})
.catch(function(error) {
console.log(error);
return {}
});
}
so I changed 'result.user.ie' to 'result.user.ze'. I know there is another way to generate the token because on firebase doc they say 'Use User.getToken() instead.' I tried and no success. Maybe someone who has experienced it can help me ?
.ze or .ie sound like non public fields, as you said, you could use the getToken method. which returns a promise resolving with the jwt token. something like
user.getToken().then(token => {/* do something with the token*/})
see the firebase docs:

How to get the access token from Google Sign-In Javascript SDK?

I have a simple single-page javascript webapp which uses "Google Sign-In for Websites": https://developers.google.com/identity/sign-in/web/sign-in
How can I get an access token for the user? I need a verifiable assertion of the user's identity on my server. I don't want offline access; I just want to know that when the web client sends an ajax request to my server, I can trust the identity of the logged-in user.
For verification purposes it would be better to use the id_token which is part of the auth response, and can be retrieved at any point like this:
gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse().id_token
The Google API Client libraries offer functions to verify the id_token and give you the associated user information on the server side: https://developers.google.com/api-client-library/
First, you need to initialize the SDK
Then call the following function to get the access-token
gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse().access_token;
This solution help for me to get access token in javascript.
Hope your are doing well.
Here is the solution, You may try this:
Actually there is no such a function name getAccessToken (Android Only) define in GoogleSignin.android.js as written here https://github.com/devfd/react-native-google-signin.
But the best part is they have already implemented the solution in GoogleSignin.android.js. just take a look at the code below from GoogleSignin.android.js
currentUserAsync() {
return new Promise((resolve, reject) => {
const sucessCb = DeviceEventEmitter.addListener('RNGoogleSignInSilentSuccess', (user) => {
this._user = user;
RNGoogleSignin.getAccessToken(user).then((token) => {
this._user.accessToken = token;
this._removeListeners(sucessCb, errorCb);
resolve(this._user);
})
.catch(err => {
this._removeListeners(sucessCb, errorCb);
resolve(this._user);
});
});
The thing is only we have do use this code wisely.
I have use the below code to get access_token and it help me to solve my access token problem.
I change above function like this in GoogleSignin.android.js
currentUserAsync() {
return new Promise((resolve, reject) => {
const sucessCb = DeviceEventEmitter.addListener('RNGoogleSignInSilentSuccess', (user) => {
this._user = user;
RNGoogleSignin.getAccessToken(user).then((token) => {
this._user.accessToken = token;
this._removeListeners(sucessCb, errorCb);
resolve(token);
})
.catch(err => {
this._removeListeners(sucessCb, errorCb);
resolve(this._user);
});
});
and I call this function like this from index.android.js.
_signIn() {
GoogleSignin.signIn()
.then((user) => {
console.log('this1' + JSON.stringify(user));
this.setState({user: user});
var gettoken = GoogleSignin.currentUserAsync(user).then((token) => {
console.log('USER token', token);
this.setState({user: user});
}).done();
}).catch((err) => {
console.log('WRONG SIGNIN', err);
})
.done();
}
You can call it as a individual function it look like this.
in GoogleSignin.android.js
getAccessTok(user)
{
RNGoogleSignin.getAccessToken(user).then((token) => {
this._user.accessToken = token;
resolve(token);
})
.catch(err => {
this._removeListeners(sucessCb, errorCb);
console.log('got error');
resolve(this._user);
});
}
and from index.android.js just call this function like this
_getToken(){
console.log(GoogleSignin.getAccessTok(this.state.user));
}
only you have to do is to pass the current user to get access token.
Hope this will help you.Have a great day.Thank You.
Yeah, it is 2021. And I was facing the same problem.
My solution is
gapi.signin2.render(this.id, {
scope: this.scope,
width: this._width,
height: this._height,
longtitle: this._longTitle,
theme: this.theme,
// Set to true, otherwise only user actively logging in with Google will have access token
onsuccess: (googleUser: gapi.auth2.GoogleUser) => googleUser.getAuthResponse(true),
onfailure: () => this.handleFailure()
});

Categories