I'm using the LinkedIn Javascript API to sign in users to my application, however the API is not returning the email address even though I'm requiring permission for that specific field. I'm including the API script as follows:
<script type="text/javascript" src="//platform.linkedin.com/in.js">
api_key: API_KEY
scope: r_fullprofile r_emailaddress
</script>
then I'm including the Log In button in the markup:
<script type="in/Login" data-onAuth="onLinkedInAuth">
and finally I have a function to add the callback for the API response:
function onLinkedInAuth() {
var fields = ['first-name', 'last-name', 'email-address'];
IN.API.Profile("me").fields(fields).result(function(data) {
console.log(data);
}).error(function(data) {
console.log(data);
});
};
I'm only getting the First and Last Name but the API doesn't return the email field.
Reference: https://developer.linkedin.com/documents/profile-fields#email
1- be sure you made email permission (r_emailaddress) in your app http://developer.linkedin.com/documents/authentication#granting
2- then you may use this
<script type="text/javascript" src="http://platform.linkedin.com/in.js">
api_key: key
**onLoad: onLinkedInLoad**
authorize: true
</script>
<script>
function onLinkedInLoad() {
IN.Event.on(IN, "auth", onLinkedInAuth);
}
// 2. Runs when the viewer has authenticated
function onLinkedInAuth() {
IN.API.Profile("me").fields("first-name", "last-name", "email-address").result(function (data) {
console.log(data);
}).error(function (data) {
console.log(data);
});
}
</script>
hope this will help you :)
thanks
Hello there #Ulises Figueroa,
May be I am coming in a bit late but this is how I had got this done:
Start off with the initial script tag on the top of your page within the head section:
<script>
Client Id Number here:
onLoad: onLinkedInLoad
authorize: true
</script>
Then, in your JS File,(I had placed an external JS File to process this API sign up/ Auth), have the following details placed:
function onLinkedInLoad() {
IN.Event.on(IN, "auth", getProfileData);
}
function onSuccess(data) {
console.log(data);
}
function onError(error) {
console.log(error);
}
function getProfileData(){
IN.API.Profile("me").fields(["firstName","lastName", "email-address", "positions"]).result(function(data) {
var profileData = data.values[0];
var profileFName = profileData.firstName;
var profileLName = profileData.lastName;
if(data.values[0].positions._total == "0" || data.values[0].positions._total == 0 || data.values[0].positions._total == undefined) {
console.log("Error on position details");
var profileCName = "Details Are Undefined";
}
else {
var profileCName = profileData.positions.values["0"].company.name;
}
var profileEName = profileData.emailAddress;
//console.log all the variables which have the data that
//has been captured through the sign up auth process and
//you should get them...
});
}
Then last but not the least, add the following in your HTML DOCUMENT which can help you initiate the window popup for the linkedin auth sign up form:
<script type="in/Login"></script>
The above setup had worked for me. Sure this will help you out.
Cheers and have a nice day.
Implementation looks good. I'd believe this is a result from the profile's privacy settings. Per linked-in's docs:
Not all fields are available for all profiles. The fields available depend on the relationship between the user you are making a request on behalf of and the member, the information that member has chosen to provide, and their privacy settings. You should not assume that anything other than id is returned for a given member.
I figured out that this only happens with certain LinkedIn accounts, so this might be caused because some privacy setting with the email. I couldn't find any reference to the documentation so I had to consider the case when email field is not available.
Related
I'm trying to add a login/logout to/from google by their guide:
https://developers.google.com/identity/sign-in/web/sign-in
But I'm facing some problems.
index.html:
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://apis.google.com/js/platform.js" async defer></script>
<meta name="google-signin-client_id" content="**my-google-api-key**.apps.googleusercontent.com">
<script>
gapi.load('auth2',function () {
gapi.auth2.init();
});
</script>
app.component.html:
<div class="g-signin2" data-onsuccess="onSignIn"></div>
Sign out
app.component.ts:
public onSignIn(googleUser):void {
var profile = googleUser.getBasicProfile();
console.log('ID: ' + profile.getId()); // Do not send to your backend! Use an ID token instead.
console.log('Name: ' + profile.getName());
console.log('Image URL: ' + profile.getImageUrl());
console.log('Email: ' + profile.getEmail());
}
public signOut():void {
var auth2 = gapi.auth2.getAuthInstance();
auth2.signOut().then(function () {
console.log('User signed out.');
});
}
Problems:
After logging in succussfully, onSignIn function does not get called so nothing is printed but the signIn is working.
In the signOut function I have error: "Cannot find name 'gapi'." but the signout is working.
Question:
Google tells us not to use the googleUser.getBasicProfile().getId() as the user ID but use the ID Token intead: googleUser.getAuthResponse().id_token.sub.
Why?
I solved it by using NgZone. Not sure if it's the best way but it's the best until I'll find another one :)
import { Component, NgZone } from '#angular/core';
......
......
constructor(ngZone: NgZone) {
window['onSignIn'] = (user) => ngZone.run(() => this.onSignIn(user));
}
......
......
onSignIn(googleUser) {
//now it gets called
......
}
you can simply add your onSignIn method to window to get called, by following code.
constructor() {
const _self = this;
window['onSignIn'] = function (user) {
_self.onSignIn(user);
};
}
onSignIn(googleUser) {
// sign in code
}
may this link help for your last question.
Authenticate with a backend server
they described:
Warning: Do not accept plain user IDs, such as those you can get with the GoogleUser.getId() method, on your backend server. A modified
client application can send arbitrary user IDs to your server to
impersonate users, so you must instead use verifiable ID tokens to
securely get the user IDs of signed-in users on the server side.
mrgoos answer helped me, but we can make it cleaner without NGZone:
constructor() {
window['onSignIn'] = this.onSignIn;
}
My aim is to output some of my Google Analytics data inside a new-tab page using a Chrome extension.
I've followed the "Hello Analytics API: JavaScript quickstart for web applications" found at
https://developers.google.com/analytics/devguides/reporting/core/v3/quickstart/web-js#clientId as the basis for my new-tab page:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello Analytics - A quickstart guide for JavaScript</title>
</head>
<body>
<button id="auth-button" hidden>Authorize</button>
<h1>Hello Analytics</h1>
<textarea cols="80" rows="20" id="query-output"></textarea>
<script>
// Replace with your client ID from the developer console.
var CLIENT_ID = 'TAKEN OUT FOR SECURITY';
// Set authorized scope.
var SCOPES = ['https://www.googleapis.com/auth/analytics.readonly'];
function authorize(event) {
// Handles the authorization flow.
// `immediate` should be false when invoked from the button click.
var useImmdiate = event ? false : true;
var authData = {
client_id: CLIENT_ID,
scope: SCOPES,
immediate: useImmdiate
};
gapi.auth.authorize(authData, function(response) {
var authButton = document.getElementById('auth-button');
if (response.error) {
authButton.hidden = false;
}
else {
authButton.hidden = true;
queryAccounts();
}
});
}
function queryAccounts() {
// Load the Google Analytics client library.
gapi.client.load('analytics', 'v3').then(function() {
// Get a list of all Google Analytics accounts for this user
gapi.client.analytics.management.accounts.list().then(handleAccounts);
});
}
function handleAccounts(response) {
// Handles the response from the accounts list method.
if (response.result.items && response.result.items.length) {
// Get the first Google Analytics account.
var firstAccountId = response.result.items[0].id;
// Query for properties.
queryProperties(firstAccountId);
} else {
console.log('No accounts found for this user.');
}
}
function queryProperties(accountId) {
// Get a list of all the properties for the account.
gapi.client.analytics.management.webproperties.list(
{'accountId': accountId})
.then(handleProperties)
.then(null, function(err) {
// Log any errors.
console.log(err);
});
}
function handleProperties(response) {
// Handles the response from the webproperties list method.
if (response.result.items && response.result.items.length) {
// Get the first Google Analytics account
var firstAccountId = response.result.items[0].accountId;
// Get the first property ID
var firstPropertyId = response.result.items[0].id;
// Query for Views (Profiles).
queryProfiles(firstAccountId, firstPropertyId);
} else {
console.log('No properties found for this user.');
}
}
function queryProfiles(accountId, propertyId) {
// Get a list of all Views (Profiles) for the first property
// of the first Account.
gapi.client.analytics.management.profiles.list({
'accountId': accountId,
'webPropertyId': propertyId
})
.then(handleProfiles)
.then(null, function(err) {
// Log any errors.
console.log(err);
});
}
function handleProfiles(response) {
// Handles the response from the profiles list method.
if (response.result.items && response.result.items.length) {
// Get the first View (Profile) ID.
var firstProfileId = response.result.items[0].id;
// Query the Core Reporting API.
queryCoreReportingApi(firstProfileId);
} else {
console.log('No views (profiles) found for this user.');
}
}
function queryCoreReportingApi(profileId) {
// Query the Core Reporting API for the number sessions for
// the past seven days.
gapi.client.analytics.data.ga.get({
'ids': 'ga:' + profileId,
'start-date': '7daysAgo',
'end-date': 'today',
'metrics': 'ga:sessions'
})
.then(function(response) {
var formattedJson = JSON.stringify(response.result, null, 2);
document.getElementById('query-output').value = formattedJson;
})
.then(null, function(err) {
// Log any errors.
console.log(err);
});
}
// Add an event listener to the 'auth-button'.
document.getElementById('auth-button').addEventListener('click', authorize);
</script>
<script src="https://apis.google.com/js/client.js?onload=authorize"></script>
</body>
</html>
I get the following errors:
Refused to execute inline script because it violates the following
Content Security Policy directive: "script-src 'self' blob:
filesystem: chrome-extension-resource:". Either the 'unsafe-inline'
keyword, a hash
('sha256-ZJ1hGXIQLHmnXhFZqYWEDfv/ypJQ/Yvh6mYGne3Nf0s='), or a nonce
('nonce-...') is required to enable inline execution.
Refused to load the script 'https://apis.google.com/js/client.js?onload=authorize' because it violates the following Content Security Policy directive: "script-src 'self' blob: filesystem: chrome-extension-resource:".
Please advise.
Thanks,
Jack
By default, inline script(Your first error) won't be executed, and only local script is loaded (Your second error).
To solve this, take a look at Content Security Policy, the recommendation would be extracting inline script to an external script (Your first error) and making a local copy of remote script (Your second error).
I'm implementing "Google Sign In" into my website to handle all user authentication etc.. I will have a back-end database that I use to store information against users to keep track of their profile and their actions etc..
I've followed the Google Developer documentation and have got a "Google Sign In" button on a web page and when this button is clicked I choose my account and am signed in and the id_token goes off and is authenticated with my back-end server successfully. The only problem I'm now having is that when I refresh the page the button is back to "Sign In" rather than staying signed in, is this normal behaviour or is there something I'm missing? I don't want users to have to have to sign in again whenever the page changes.
On a side note I have managed to store the id_token from successfully logging into Google in localStorage and then using this id_token to re-authenticate with the back-end server automatically (as you can see in the commented out code) but this doesn't obviously automatically change the status of the "Google Sign In" button which would confuse users on the client-side.
Can anyone shed any light on this problem please?
Not signed in:
After signing in (doesn't currently stay like this after a page refresh):
login.html:
<!DOCTYPE html>
<html>
<head>
<title>Login</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="./css/base.css"/> <!-- Base CSS -->
<script src="./js/all.js"></script> <!-- All JavaScript file -->
<script src="./js/Logger.class.js"></script> <!-- Logger class -->
<script src="./bower_components/jquery/dist/jquery.min.js"></script> <!-- jQuery -->
<script src="./js/gSignIn.js"></script>
<!-- Polymer -->
<script src="./bower_components/webcomponentsjs/webcomponents-lite.min.js"></script> <!-- Web Components Import -->
<!-- Element Imports -->
<link rel="import" href="./bower_components/paper-button/paper-button.html"/>
<link rel="import" href="./bower_components/google-signin/google-signin.html"/>
</head>
<body>
<google-signin id="gSignIn" client-id="--- REMOVED FOR PRIVACY ---" scopes="profile email openid"></google-signin>
Sign Out
</body>
</html>
gSignIn.js:
/**
* Google Sign In JavaScript
*/
$(document).ready(function() {
var logger = new Logger("gSignIn.js", false); // logger object
var id_token = null;
logger.log("Load", "Successful");
// Try to automatically login
// if (localStorage !== null) { // If local storage is available
// if (localStorage.getItem("gIDToken") !== null) { // If the Google ID token is available
// id_token = localStorage.getItem("gIDToken");
// // Send off AJAX request to verify on the server
// $.ajax({
// type: "POST",
// url: window.api.url + "googleauth/verify/",
// data: { "id_token": id_token },
// success: function (data) {
// if (!data.error) { // If there was no error
// logger.log("Google SignIn", "Successfully signed in!");
// }
// }
// });
// }
// }
/**
* EVENT: Google SignIn success
*/
$("#gSignIn").on("google-signin-success", function () {
id_token = getGoogleAuthResponse().id_token;
var profile = getGoogleProfile();
console.log("ID: " + profile.getId()); // Don't send this directly to your server!
console.log("Name: " + profile.getName());
console.log("Image URL: " + profile.getImageUrl());
console.log("Email: " + profile.getEmail());
// Send off AJAX request to verify on the server
$.ajax({
type: "POST",
url: window.api.url + "googleauth/verify/",
data: { "id_token": id_token },
success: function (data) {
if (!data.error) { // If there was no error
logger.log("Google SignIn", "Successfully signed in!");
// Store the id_token
if (localStorage !== null) { // If localStorage is available
localStorage.setItem("gIDToken", id_token); // Store the id_token
}
}
}
});
});
$("#signOut").click(function () {
var auth2 = gapi.auth2.getAuthInstance();
auth2.signOut().then(function () {
console.log("User signed out.");
});
});
/**
* Get Google Profile
*
* #returns object
*/
var getGoogleProfile = function () {
var profile = gapi.auth2.getAuthInstance().currentUser.get().getBasicProfile();
return profile;
};
/**
* Get Google Auth Response
*
* #returns object
*/
var getGoogleAuthResponse = function () {
var response = gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse();
return response;
};
});
Thanks!
I had the same problem and, after ensuring third party cookies were enabled, it came down to the hostname, localhost in this case.
In the end, I had to fake a domain using /etc/hosts, ensure google developers dashboard has that domain whitelisted, and start using that domain instead of localhost.
I can only assume that gapis don't like localhost, even though it's whitelisted in my google developers dashboard for the account I'm using. If you do manage to get localhost to work, do give me a shout!
Another way to do this is to access localhost from a nonstandard port (not 80). I managed to get around this headache by using an nginx proxy from port 80 to 81:
server {
listen 81;
location / {
proxy_pass http://localhost:80;
}
}
I have attempted to go about the use of Paypal Lightbox a bit differently.
I have used a button to trigger an ajax call which then generates the PayKey and if all goes well then triggers the form (from the documentation) to be created and submitted.
When i click the button the lightbox html is created but the content is not loaded into it. Instead i get the error:
Load denied by X-Frame-Options: https://www.sandbox.paypal.com/us/cgi-bin/webscr?cmd=_dispatch-failed does not permit cross-origin framing.
My Code:
<head>
<script src="https://www.paypalobjects.com/js/external/dg.js" type="text/javascript"></script>
</head>
External Script:
$("#checkout").click(function() {
var id = $(this).data("id");
if(id) { pay(id); }
});
function pay(id) {
$.ajax({
url : 'paypal/Pay-Chained.php',
type : 'POST',
data : "id="+id,
success : function (data) {
var info = (JSON.parse(data));
if (info['Type'] == 'Success') {
var output = info['URL'].substr(0, 64) + "expType=light&" + info['URL'].substr(64);
$("body").append('<form action="'+output+'" target="PPDGFrame" class="standard"><input type="submit" id="submitBtn"></form>');
$("#submitBtn").click();
} else {
alert("Error: Please try again or contact support.");
}
},
error : function () {
alert("Error: Please try again.");
}
});
}
At the bottom of the buttons page:
<script type="text/javascript" charset="utf-8">
var embeddedPPFlow = new PAYPAL.apps.DGFlow({trigger: 'checkout'});
</script>
I am thinking maybe it has to do with the order things are executed but can't seem to figure it out. Any help would be great!
EDIT: I just created a blank page and copied the script from the documentation exactly. I still get the same error. Might it have something to do with server settings? I am running a WampServer with an address like 192.168.1.1/mysite/index.html.
Im currently trying to get users timeline data from twitter through the oauth process and I cant get it to work.
I tried a few things here http://bytespider.github.com/jsOAuth/ and I keep running into the same problem.
Whoa there!
There is no request token for this page. That's the special key we need from applications asking to use your Twitter account. Please go back to the site or application that sent you here and try again; it was probably just a mistake.
It cant be this hard to do this right?
Here is my code
<html>
<head>
<title></title>
</head>
<body>
<script src="jsOAuth-1.3.4.min.js"></script>
<script>
var config = {
consumerKey: "[removed]",
consumerSecret: "[removed]",
requestTokenUrl: "https://api.twitter.com/oauth/request_token",
authorizationUrl: "https://api.twitter.com/oauth/authorize",
accessTokenUrl: "https://api.twitter.com/oauth/access_token"
};
var oauth = new OAuth(config);
oauth.fetchRequestToken(openAuthoriseWindow, failureHandler);
function openAuthoriseWindow(url)
{
var wnd = window.open(url, 'authorise');
setTimeout(waitForPin, 100);
function waitForPin()
{
if (wnd.closed)
{
var pin = prompt("Please enter your PIN", "");
oauth.setVerifier(pin);
oauth.fetchAccessToken(getSomeData, failureHandler);
}
else
{
setTimeout(waitForPin, 100);
}
}
}
function getSomeData()
{
oauth.get("https://api.twitter.com/oauth/something/?format=jsonp", function (data) {
console.log(data.text);
}, failureHandler);
}
function failureHandler(data)
{
console.error(data);
}
</script>
</body>
</html>
I also get this error in console
OPTIONS https://api.twitter.com/oauth/request_token 403 (Forbidden)
EDIT: Does anyone know how to do this? Cant even find a good resource on twitter. Also can you achieve this without pin and just have users enter their login details?
Thanks in advance