Google drive authentication showing error "idpiframe_initialization_failed" - javascript

I am trying to use google drive javascript API. I have set the OAuth consent also. But everytime its showing error
Not a valid origin for the client
and
"idpiframe_initialization_failed"
what is the problem actually? I have googled, googled and googled but no solution with that. I am trying on localhost by creating a virtual host.
I am using the sample from google doc
<html>
<head></head>
<body>
<script type="text/javascript">
function handleClientLoad() {
// Loads the client library and the auth2 library together for efficiency.
// Loading the auth2 library is optional here since `gapi.client.init` function will load
// it if not already loaded. Loading it upfront can save one network request.
gapi.load('client:auth2', initClient);
}
function initClient() {
// Initialize the client with API key and People API, and initialize OAuth with an
// OAuth 2.0 client ID and scopes (space delimited string) to request access.
gapi.client.init({
apiKey: 'APIKEY',
discoveryDocs: ["https://people.googleapis.com/$discovery/rest?version=v1"],
clientId: 'CLIENTID.apps.googleusercontent.com ',
scope: 'profile'
}).then(function () {
// Listen for sign-in state changes.
gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);
// Handle the initial sign-in state.
updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
});
}
function updateSigninStatus(isSignedIn) {
// When signin status changes, this function is called.
// If the signin status is changed to signedIn, we make an API call.
if (isSignedIn) {
makeApiCall();
}
}
function handleSignInClick(event) {
// Ideally the button should only show up after gapi.client.init finishes, so that this
// handler won't be called before OAuth is initialized.
gapi.auth2.getAuthInstance().signIn();
}
function handleSignOutClick(event) {
gapi.auth2.getAuthInstance().signOut();
}
function makeApiCall() {
// Make an API call to the People API, and print the user's given name.
gapi.client.people.people.get({
'resourceName': 'people/me',
'requestMask.includeField': 'person.names'
}).then(function(response) {
console.log('Hello, ' + response.result.names[0].givenName);
}, function(reason) {
console.log('Error: ' + reason.result.error.message);
});
}
</script>
<script async defer src="https://apis.google.com/js/api.js"
onload="this.onload=function(){};handleClientLoad()"
onreadystatechange="if (this.readyState === 'complete') this.onload()">
</script>
<button id="signin-button" onclick="handleSignInClick()">Sign In</button>
<button id="signout-button" onclick="handleSignOutClick()">Sign Out</button>
</body>
</html>

I had the same problem with Google Drive javascript API quick start example.
I cleared Google Chrome's cache from beginning of time and after that it worked...
Hope it helps! :)

You should provide the http calls and response so we can check.
However the message "Not a valid origin for the client" suggests that the URL you are serving your web page from is not one of those origins that you configrued in the API Console.

Related

Keycloak JavaScript API to get current logged in user

We plan to use keycloak to secure a bunch of web apps, some written in Java, some in JavaScript (with React).
After the user is logged in by keycloak, each of those web apps needs to retrieve the user that is logged in and the realm/client roles that the user has.
For Java apps, we tried the keycloak Java API (request -> KeycloakSecurityContext -> getIdToken -> getPreferredUsername/getOtherClaims). They seem to work fine
For JavaScript apps, we tried the following code, but could not get Keycloak to init successfully (Note this is in web app code after the user is already authenticated by keycloak, the app is only trying to retrieve who logged in with what roles):
var kc = Keycloak({
url: 'https://135.112.123.194:8666/auth',
realm: 'oneRealm',
clientId: 'main'
});
//this does not work as it can't find the keycloak.json file under WEB-INF
//var kc = Keycloak('./keycloak.json');
kc.init().success(function () {
console.log("kc.idToken.preferred_username: " + kc.idToken.preferred_username);
alert(JSON.stringify(kc.tokenParsed));
var authenticatedUser = kc.idTokenParsed.name;
console.log(authenticatedUser);
}).error(function () {
window.location.reload();
});
I assume it would be fairly common that web apps need to retrieve current user info. Anyone knows why the above code didn't work?
Thanks.
<script src="http://localhost:8080/auth/js/keycloak.js" type="text/javascript"></script>
<script type="text/javascript">
const keycloak = Keycloak({
"realm": "yourRealm",
"auth-server-url": "http://localhost:8080/auth",
"ssl-required": "external",
"resource": "yourRealm/keep it default",
"public-client": true,
"confidential-port": 0,
"url": 'http://localhost:8080/auth',
"clientId": 'yourClientId',
"enable-cors": true
});
const loadData = () => {
console.log(keycloak.subject);
if (keycloak.idToken) {
document.location.href = "?user="+keycloak.idTokenParsed.preferred_username;
console.log('IDToken');
console.log(keycloak.idTokenParsed.preferred_username);
console.log(keycloak.idTokenParsed.email);
console.log(keycloak.idTokenParsed.name);
console.log(keycloak.idTokenParsed.given_name);
console.log(keycloak.idTokenParsed.family_name);
} else {
keycloak.loadUserProfile(function() {
console.log('Account Service');
console.log(keycloak.profile.username);
console.log(keycloak.profile.email);
console.log(keycloak.profile.firstName + ' ' + keycloak.profile.lastName);
console.log(keycloak.profile.firstName);
console.log(keycloak.profile.lastName);
}, function() {
console.log('Failed to retrieve user details. Please enable claims or account role');
});
}
};
const loadFailure = () => {
console.log('Failed to load data. Check console log');
};
const reloadData = () => {
keycloak.updateToken(10)
.success(loadData)
.error(() => {
console.log('Failed to load data. User is logged out.');
});
}
keycloak.init({ onLoad: 'login-required' }).success(reloadData);
</script>
simple javascript client authentication no frameworks.
for people who are still looking...
Your code asks the Keycloak client library to initialize, but it doesn't perform a login of the user or a check if the user is already logged in.
Please see the manual for details: http://www.keycloak.org/docs/latest/securing_apps/index.html#_javascript_adapter
What your probably want to do:
Add check-sso to the init to check if the user is logged in and to retrieve the credentials keycloak.init({ onLoad: 'check-sso' ... }). You might even use login-required.
Make sure that you register a separate client for the front-end. While the Java backend client is of type confidential (or bearer only), the JavaScript client is of type public.
You find a very minimal example here: https://github.com/ahus1/keycloak-dropwizard-integration/blob/master/keycloak-dropwizard-bearer/src/main/resources/assets/ajax/app.js
Alternatively you can register a callback for onAuthSuccess to be notified once the user information has been retrieved.
Once you use Keycloak in the front-end, you will soon want to look in bearer tokens when calling REST resources in the backend.
You might have solved the problem by this time. I hope this answer help rest of the people in trouble.
when you use JavaScript Adopter
Below javascript should be added in of html page.
<script src="http://localhost:8080/auth/js/keycloak.js"></script>
<script>
/* If the keycloak.json file is in a different location you can specify it:
Try adding file to application first, if you fail try the another method mentioned below. Both works perfectly.
var keycloak = Keycloak('http://localhost:8080/myapp/keycloak.json'); */
/* Else you can declare constructor manually */
var keycloak = Keycloak({
url: 'http://localhost:8080/auth',
realm: 'Internal_Projects',
clientId: 'payments'
});
keycloak.init({ onLoad: 'login-required' }).then(function(authenticated) {
alert(authenticated ? 'authenticated' : 'not authenticated');
}).catch(function() {
alert('failed to initialize');
});
function logout() {
//
keycloak.logout('http://auth-server/auth/realms/Internal_Projects/protocol/openid-connect/logout?redirect_uri=encodedRedirectUri')
//alert("Logged Out");
}
</script>
https://www.keycloak.org/docs/latest/securing_apps/index.html#_javascript_adapter Reference Link.
Note : Read the comments for 2 methods of adding json credentials.

how to use google cloud storage for javascript

I've followed the guide on how to use GCS on their site:
but
Once Unauthorized used
I then get
Failed to load resource: the server responded with a status of 400 ()
{"error":{"errors":[{"domain":"usageLimits","reason":"keyInvalid","message":"Bad
Request"}],"code":400,"message":"Bad Request"}}
Here is my step
create the javascript page from this
authSample.html
change clientId to google console page
OAuth 2.0 user ID:??????????????????????.apps.googleusercontent.com
change apiKey to google console page
OAuth 2.0 user api key
run the authSample.html
What am I doing wrong?
So this bug occurs because of an incorrect way of loading and authorising API's.
The correct way is to first use
gapi to load client (no auth required)
next load, the "storage","v1"
finally Authorise
gapi.load('client', () => {
gapi.client.load('storage', 'v1', authResult =>{
gapi.auth.authorize({
client_id: CLIENT_ID,
scope: SCOPES,
immediate: false
},authResult=>{
if (authResult && !authResult.error) {
var request = gapi.client.storage.buckets.list({
'project': PROJECT_ID
});
request.execute(function(resp) {
console.log(resp)
});
} else {
alert("Un-Authorised")
}
});
});
});
The supported client libraries are limited to a number of languages only. If you wish to build a solution around those, you can refer these here
https://cloud.google.com/storage/docs/json_api/v1/libraries#api-client-libraries

LinkedIn Login with basic example not working

I would like to add the possibility of LinkedIn login to my project. I followed the tutorial given on the LinkedIn developer page and ended up with the following code, really basic stuff from that tutorial:
<!-- linkedin login -->
<script type="text/javascript" src="//platform.linkedin.com/in.js">
api_key: [MY_API_KEY] {~n}
authorize: false {~n}
onLoad: onLinkedInLoad {~n}
</script>
<!-- linkedin login play -->
<script type="text/javascript">
// Setup an event listener to make an API call once auth is complete
function onLinkedInLoad() {
IN.Event.on(IN, "auth", getProfileData);
}
// Handle the successful return from the API call
function onSuccess(data) {
console.log(data);
}
// Handle an error response from the API call
function onError(error) {
console.log(error);
}
// Use the API call wrapper to request the member's basic profile data
function getProfileData() {
IN.API.Raw("/people/~").result(onSuccess).error(onError);
}
</script>
Don't mind the {~n} as I'm using dust.js to render the page and I need them to pass the arguments to the LinkedIn script.
So, the login button appears, this means that LinkedIn was able to connect to my API key correctly, but the Chrome console gives me the following error: Uncaught Error: Could not execute 'onLinkedInLoad'. Please provide a valid function for callback.. Since this is the example given on the tutorial page, I don't know what can be wrong with it. Even if I declare the block of LinkedIn login functions before the call to the LinkedIn in.js, I get the same error.
I think it is a very easy mistake to spot, but I cannot really tell what am I doing wrong.
This is happening cause you are calling onLinkedInLoad() in head section,and if you are working on multiple pages..it will be called on the every page even if it doesn't have data from API call(or simply you are not making any call on the page where this error is appearing).
Try this`
// Removing event listener by calling IN.Event.on() outside of onLinkedInLoad()
IN.Event.on(IN, "auth", getProfileData);
// Handle the successful return from the API call
function onSuccess(data) {
console.log(data);
}
// Handle an error response from the API call
function onError(error) {
console.log(error);
}
// Use the API call wrapper to request the member's basic profile data
function getProfileData() {
IN.API.Raw("/people/~").result(onSuccess).error(onError);
}
`
And Yes remove " onLoad: onLinkedInLoad {~n}" from first script call

Apply by LinkedIn Button, 400 error bad request

I'm trying to add an 'Apply by LinkedIn' button to an expressionengine site. I've created my app on LinkedIn and am using the JS SDK and have followed the guide in order to do so. My code is below:
<script type="text/javascript" src="//platform.linkedin.com/in.js">
api_key: MY CLIENT ID
authorize: true
onLoad: onLinkedInLoad
</script>
<script type="text/javascript">
// Setup an event listener to make an API call once auth is complete
function onLinkedInLoad() {
IN.Event.on(IN, "auth", getProfileData);
}
// Handle the successful return from the API call
function onSuccess(data) {
console.log(data);
}
// Handle an error response from the API call
function onError(error) {
console.log(error);
}
// Use the API call wrapper to request the member's profile data
function getProfileData() {
IN.API.Raw("/people/~:(id, first-name, skills, educations, languages, twitter-accounts)")
.result(onSuccess).error(onError);
}
</script>
I've added the button markup as suggested:
<script type="in/Login"></script>
SO the button is displayed and upon click I'm presented with my account to authorise the app, however, upon authenticating, the button disappears and I get the following error:
Failed to load resource: the server responded with a status of 400 (Bad Request)
ObjecterrorCode: 0message: "Unknown field {_first-name} in resource {Person}"requestId: "LT59BVDVU2"status: 400timestamp: 1436259208629__proto__: Object
Thanks!
Use camelcasing instead of dashes:
IN.API.Raw("/people/~:(id, firstName, skills, educations, languages, twitter-accounts)")

Google Javascript API (gapi) - problems with .load

I am trying to use the Google plus API (via googie-api-javascript) implementation like so (omitting full code):
var clientId = '7454475891XxxxxxXom4c6n.apps.googleusercontent.com'; //fake client
var apiKey = '-uTH_p6NokbrXXXXXXXXXXXXX'; //Fake Key
var scopes = 'https://www.googleapis.com/auth/plus.me';
function handleClientLoad() {
gapi.client.setApiKey(apiKey);
window.setTimeout(checkAuth,1);
}
function checkAuth() {
gapi.auth.authorize({client_id: clientId, scope: scopes, immediate: true}, handleAuthResult);
}
function handleAuthResult(authResult) {
if (authResult && !authResult.error) {
makeApiCall();
} else {
//handle user-approval
}
}
// Load the API and make an API call. Display the results on the screen.
function makeApiCall() {
gapi.client.load('plus', 'v1', function() {
var o = gapi.client.plus;
alert(o);
});
}
The code works well upto the point of gapi.client.load (including the user allowing access) - this callback gets called but alert(o) will return undefined.
Upon inspecting the HTTP request I see the .load issues a request to:
https://content.googleapis.com/discovery/v1/apis/plus/v1/rpc?fields=methods%2F*%2Fid&pp=0&key=-uTH_p6NokbrXXXXXXXX
This returns HTTP 400 with the following message:
{"error":{"errors":[{"domain":"usageLimits","reason":"keyInvalid","message":"Bad Request"}],"code":400,"message":"Bad Request"}}
My question is - what do I need to change to make this work?
Is there some secret setting I need to enable ? Google+ is enabled in the google-developer-console under the APIs list.
Thanks for the help,
Alon
Problem:
.load issues a request to the google discovery service to load the .JS. The service will error out if the request it receives contains an api-key. (I don't know why the library works like this, it seems like a bug?)
Fix:
gapi.client.setApiKey(""); //NEW
gapi.client.load('plus', 'v1', function()
//re-add the key later if you need it
From Discovery Service docs:
requests you make to the Discovery Service API should not include an API key. If you do provide a key, the requests will fail.
Weird... :P
A little update & more of an explanation. The current Discovery Service page is a little more specific now. They indicate that if the app has an Oauth2 token, then the API Key value is not required. However, I also found that if I have an authenticated user and thus an Oauth2 token (access_token) present, the Discovery Service fails with the error noted in the OP. This seems to contradict the documentation.
You can see the token in the developer tools console with:
console.log(gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse());
Embed that somewhere in a <script>...</script>in your HTML or in a .js file that is called otherwise. Must be after gapi.load(...). It'll stop the script if executed before gapi.load(...) is called.
To get a current user this has to be after the user is authenticated, of course. It does return an object if a user has not been authenticated however. If you are in Chrome, you can expand The Object in the developer tools console window to get a nice outline format of all the stuff in the auth response.
Note that currentUser is undefined prior to a successful authentication. Since this 'fails silently' you should use a conditional statement to verify either the sign in status or that a current user exists in your real code.
For completeness the object instantiation process in my app goes like this, at a high level:
1.) gapi.load(...) - After this gapi.client, gapi.auth2 and other objects are available.
2.) gapi.client.setApiKey("") would be called to 'clear' the api key if it had been set previously for some other purpose.
3.) gapi.auth2.init(...) - After this the auth instance is available via gapi.auth2.getAuthInstance .
4.) Then the login is kicked off using the .signIn() method of the auth instance. The auth instance would be instantiated with something like auth_instance = gapi.auth2.getAuthInstance(); If that's how you do it then the sign in would be auth_instance.signIn().
(...) - means there are several parameters needed.
I also found the Google tictactoe example useful as an example and a simple base for further work.
I hope this is helpful to someone!
you need to call the method
function handleAuthClick(event) {
gapi.auth.authorize({client_id: clientId, scope: scopes, immediate: false} handleAuthResult);
return false;
}
function makeApiCall() {
gapi.client.load('plus', 'v1', function () {
var request = gapi.client.plus.people.get({
'userId': 'me'
});
request.execute(function (resp) {
'method ajax with you application'
});
});
}
you can see what this do here

Categories

Resources