Similar question was already asked, and the issue was gapi.auth.signout() doesn't work in localhost: gapi.auth.signOut(); not working I'm lost
But it worked fine on a real website, until just suddenly, with no changes on my end. It will not sign the user out now, so if they logout of my site, their Google authentication is still live. Here's some example code, which I think should not say the user is still signed in:
gapi.auth.authorize({ 'client_id': CLIENT_ID, 'scope': SCOPES, 'immediate': false, cookie_policy: 'single_host_origin'}, function (authResult) {
gapi.auth.signOut();
setTimeout(function() {
gapi.auth.authorize({ 'client_id': CLIENT_ID, 'scope': SCOPES, 'immediate': true, cookie_policy: 'single_host_origin'}, function (authResult) {
if (authResult && !authResult.error)
alert("Still signed in");
})
}, 5000);
});
This seems totally wrong and unsafe. I tested my original code in the past and it worked properly, so I think there may be a recent regression in the Google API.
Related
I have an iOS App with an Uber API integration where I use SSO to authenticate the user and then save the accessToken & refreshToken locally on my device. Then I'm calling my server who uses a javascript background function to call the node-uber (https://www.npmjs.com/package/node-uber) library to make a request to Uber.
So far, I'm trying to set up the uber client with my 2 local tokens from the SSO login like this:
var uber = new uberClient({
client_id: '...',
client_secret: '...',
server_token: '...',
name: 'My App',
sandbox: true, //optional
access_token: accessToken,
refresh_token: refreshToken
});
afterwards I want to call the uber.requests.getEstimatesAsync endpoint like this:
uber.requests.getEstimatesAsync({
"start_latitude": pickupLocation["lat"],
"start_longitude": pickupLocation["lng"],
"end_latitude": dropoffLocation["lat"],
"end_longitude": dropoffLocation["lng"]
})
.then(function(res) {
console.log(JSON.stringify(res));
})
.error(function(err) {
console.error(err);
});
})
Though every time I get an "invalid_grant" error 400 while doing this. Did I make a mistake authenticating myself or setting up the Uber client wrong? Is it even possible to use my SSO accessToken & refreshToken then on the uber client, which does a OAuth2 authentification? I thought that both access and refresh token should probably be the same what Uber sends back to be for SSO & OAuth2.
I'm using a Developer account for doing this, therefore I should actually have all the required permissions for the request endpoint, but I also obtained them previously in the App correctly.
This thread on the official uber documentation explains potential reasons but I guess they don't really apply to my case, do they? https://developer.uber.com/docs/riders/guides/authentication/introduction#common-problems-and-solutions
Any security expert here who can help?
Best regards,
Matt
P.S.: I also posted this question on the Uber library I'm using for making those requests, but nobody seems to be able to help me there so far. https://github.com/shernshiou/node-uber/issues/70
Edit: The following picture shows my authentication setup so far:
I found a solution. I think was a problem with the library itself. Because once I made the request with http with the "request" library (https://github.com/request/request) it worked. Include for that at the top of your code:
var request = require('request');
Both OAuth2 and SSO accessToken worked. You should give the method a pickupLocation with latitude and longitude and your obtained accessToken from Uber like this:
function getAllAvailableUberProducts(pickupLocation, accessToken){
var lat = pickupLocation["lat"].toString();
var lng = pickupLocation["lng"].toString();
var options = {
uri: "https://api.uber.com/v1.2/products?latitude="+lat+"&longitude="+lng,
method: 'GET',
headers: {
"Authorization": "Bearer " + accessToken,
"Accept-Language": "en_US",
"Content-Type": "application/json"
}
};
request(options, function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(JSON.parse(body).products);
} else {
console.log(error);
}
});
}
I hope this helps someone.
I am newbie to electron and I am currently trying to implement an OAuth2.0 API which requires a callback URI. Url callback requires valid URL (https://myserver.com/sucess). so i tried this code snippet but does not work.
// Your GitHub Applications Credentials
var options = {
client_id: 'your_client_id',
client_secret: 'your_client_secret',
scopes: ["user:email", "notifications"] // Scopes limit access for OAuth tokens.
};
app.on('ready', () => {
// Build the OAuth consent page URL
var authWindow = new BrowserWindow({ width: 800, height: 600, show: false, 'node-integration': false });
var githubUrl = 'https://github.com/login/oauth/authorize?';
var authUrl = githubUrl + 'client_id=' + options.client_id + '&scope=' + options.scopes;
authWindow.loadURL(authUrl);
authWindow.show();
function handleCallback (url) {
console.log(url);
}
// Handle the response from GitHub - See Update from 4/12/2015
authWindow.webContents.on('will-navigate', function (event, url) {
handleCallback(url);
});
authWindow.webContents.on('did-get-redirect-request', function (event, oldUrl, newUrl) {
handleCallback(newUrl);
});
// Reset the authWindow on close
authWindow.on('close', function() {
authWindow = null;
}, false);
});
also, i used angular js route but does not work either.
so I'm wondering if there is a way to run server inside electron app to serve app from URL (https://localhost:3000) and if so how this will affect app behavior at packaging and distributing time, i means does the app will run from the same port
... any suggestions will help about how i can approach this problem. thank you
I had the same issue last week, i needed to integrate my electron app with vkontakte api which uses form of OAuth protocol. What you can do:
1) You launch local node http server, probably in separate process as i did.
2) You request code through oauth link and set redirect uri as http://127.0.0.1:8000/, for some reason https://localhost didn't work for me.
3) In main process you wait for message with code from server, on server implemented corresponding logic (when you receive request and code in it send through process.send back to parent message with code)
4)You request access token from main process, you shouldn't change redirect_uri. You again catch response from your server.
5) You get access_token, you kill server...
But when i did all this i read their docs till end and there was stated that standalone apps, like mine for desktop could receive token in easier way through "implicit flow", and you can get your token with only one call. Hope my experience could be extrapolated on your issue. Good luck!
Using the auth0 passport strategy
https://github.com/auth0/passport-auth0
My callback always has null for a refresh token. Calling the auth0 lock function directly gives me a refreshtoken as expected, however using this oauth passport strategy doesn't return a refreshtoken. Do I need to pass an offline_access scope to auth0 - and if so, how do I pass it in using the Auth0Strategy?
passport.use(new Auth0Strategy({
domain: config.auth0.domain,
clientID: config.auth0.clientId,
clientSecret: config.auth0.secret,
callbackURL: '/login/return'
},
function(accessToken, refreshToken, extraParams, profile, done) {
console.log('refresh token is always null', refreshToken);
}
});
Yes, you need to request one (by adding scope=offline_access). You do this when you send the initial authorization request (e.g. via Lock, or auth0.js, or by simply following link with the right parameters). It is not dependent on passport really. Makes sense?
e.g. try with this:
app.get('/login',
passport.authenticate('auth0', {scope: 'offline_access'}), function (req, res) {
res.redirect("/");
});
2 hours trying to get this to work and I can't. Firebase authenticates the user just fine, but then it can't fetch anything from the Google Plus API.
The error you will get:
{
domain: "global"
location: "Authorization"
locationType: "header"
message: "Invalid Credentials"
reason: "authError"
}
The code is this:
Auth.$authWithOAuthPopup(provider, {
scope: ['profile', 'email']
}).then(function(authData) {
console.log(authData.token);
gapi.client.setApiKey('<APIKEY>');
gapi.client.load('plus','v1', function(){
var request = gapi.client.plus.people.get({
'userId': 'me'
});
request.execute(function(resp) {
console.log('Retrieved profile for:' + resp.displayName);
debugger;
});
});
}, showError);
It must have something to do with Firebase making the call on our behalf. Because this codepen, in which we do our own authentication, works fine:
http://codepen.io/morgs32/pen/KVgzBw
Don't forget to set clientId and apiKey in the codepen.
If you can figure this one out you're gonna get gold on christmas.
You're trying to use authData.token to access Google. But authData.token is a JWT token for accessing Firebase.
To access Google, you should use authData.google.accessToken.
Also see this page in the Firebase documentation on using the Google provider.
I'm using the google HTML sign-in button in my single page (javascript) application to obtain an authorization object from users with Google logins. This is detailed here: https://developers.google.com/+/web/signin/add-button.
I successfully receive back a token such as shown below. Since this token expires in 1 hour, I need to refresh the token every 30 minutes or so, until the user choses to log out. I am attempting this by calling:
gapi.auth.authorize({client_id: "90... ...92.apps.googleusercontent.com", scope: "profile email", immediate: true}, function() { console.log( arguments ); } );
but with no luck. I receive the same token back until it expires, after which I get back the empty (not signed in) token. How can I preserve / refresh the bearer token without the user having to continually log in again?
{
_aa: "1"
access_token: "ya29.1.AA... ...BByHpg"
authuser: "0"
client_id: "90... ...92.apps.googleusercontent.com"
code: "4/Nyj-4sVVcekiDnIgMFh14U7-QdRm.svPMQSODiXMbYKs_1NgQtmX9F90miwI"
cookie_policy: "single_host_origin",
expires_at: "1398341363",
expires_in: "3600",
g_user_cookie_policy: undefined,
id_token: "eyJhbGciOiJ... ...0Es1LI"
issued_at: "1398337763",
num_sessions: "2",
prompt: "none",
response_type: "code token id_token gsession",
scope: "https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email",
session_state: "b92d67080... ...73ae",
state: "",
status: {
google_logged_in: true,
method: "AUTO",
signed_in: true
},
token_type: "Bearer"
}
Using the client side flow (ie Java Script) you can only receive short-lived (~1 hour) access_token. If you want to be able to refresh it, you need a refresh_token which can only be obtained using the server side flow.
You can find more information here.
Basically,it works like this :
The user connects to your Website and clicks on the "Sign-in button"
You receive an access_token and a code in JavaScript
You send this code to a PHP Script on your web server
The script makes a request to Google Servers and exchanges your code for an
access_token(which should be identical to the one you just received in JavaScript) and a refresh_token
You need to store this refresh_token somewhere (in a data base for
example) because it will only be issued once (when the users grants
permission)
When one of your access_token is about to expire, you can use your
refresh_token to get another valid access_token
As well as setting a timer, you should check that your token is still valid before making the API call. Now that the client library returns promises, and promises are chainable, you can do it really elegantly.
See my gist here.