Get LinkedIn Access Token with OAuthSimple in Javascript - javascript

I'm using OAuthSimple in Javascript with PIN based authentication (OOB flow).
We are developing an HTML5 app which lives inside a mobile device's native wrapper using PhoneGap. There's not ANY server side (no URL at all), all requests are sent using the mobile device as a proxy.
So far I managed to:
- Get Request Token
- Redirect user to authorization page
- Got authorization PIN
I need sample code that shows how to get an Access Token using OAuthSimple Javascript library.
Any help will be appreciated. Thanks!

Not sure if you are the same person who posted on our forums recently (see post here https://developer.linkedin.com/forum/oauthsimple-request-access-token), but I replied with demo code on how to do just that using OAuthSimple.
The actual sample code can be found here: https://gist.github.com/efc88a38da25ff4e9283
If you need any help using it, don't hesitate to reach out!
-Jeremy

This will create a phonegap linkedIn login, its just a worked around code though, but this works atleast for me
var consumer_key = "key";
var shared_secret = "secrete";
self.oauth = OAuthSimple(consumer_key, shared_secret); var linkedInScope = 'r_basicprofile r_emailaddress w_messages r_network';
var url = self.oauth.sign({action: "GET", path: "https://api.linkedin.com/uas/oauth/requestToken", parameters: {scope: linkedInScope, oauth_callback: "oob"}}).signed_url;
var request = 'requestToken';
var linkedInObj = new Object;
function linkedInWorkAround(url,request,data){
var callType = 'GET';
var xhr = $.ajax({
url : url,
beforeSend : function(){
$.mobile.loading( 'show' );
if(request == 'linkedIn_login'){
callType = 'POST';
}
},
timeout : 8000,
data : data,
type : callType,
success: function(r){
$.mobile.loading( 'hide' );
if(request == 'requestToken'){
var oauthRes = r.split('&');
$.each(oauthRes, function(k,v){
var resObj = v.split('=')
linkedInObj[resObj[0]] = resObj[1];
});
url = 'https://www.linkedin.com/uas/oauth/authenticate?scope='+linkedInScope+'&oauth_token='+linkedInObj.oauth_token;
request = 'oauth_token';
linkedInWorkAround(url,request);
}
else if(request == 'oauth_token'){
var accessCode = $(r).find('.access-code');
if(accessCode.size()){
self.oauth.reset();
var pin = $(r).find('.access-code').text();
url = self.oauth.sign({action: "GET", path: "https://api.linkedin.com/uas/oauth/accessToken", parameters: {scope: linkedInScope, oauth_verifier: pin}, signatures: linkedInObj}).signed_url;
request = 'accessToken';
linkedInWorkAround(url,request);
}
else{
$('.custom-linkedIn').remove();
var cloneIn = $(r).find('form').addClass('custom-linkedIn').clone();
$('a,span,select,.duration-label,.access',cloneIn).hide();
$('#pageLinkedIn .errMsgHolder').after(cloneIn)
$('#session_key-oauthAuthorizeForm').textinput();
$('#session_password-oauthAuthorizeForm').textinput();
$('input[type=submit]').button();
$('form.custom-linkedIn').submit(function(){
$('.errMsgHolder').hide().text('');
url = 'https://www.linkedin.com/uas/oauth/authorize/submit';
request = 'linkedIn_login';
var data = $(this).serialize();
linkedInWorkAround(url,request,data);
return false;
});
}
}
else if(request == 'linkedIn_login'){
self.oauth.reset();
var pin = $(r).find('.access-code').text();
url = self.oauth.sign({action: "GET", path: "https://api.linkedin.com/uas/oauth/accessToken", parameters: {scope: linkedInScope, oauth_verifier: pin}, signatures: linkedInObj}).signed_url;
request = 'accessToken';
linkedInWorkAround(url,request);
}
else if(request == 'accessToken'){
var oauthRes = r.split('&');
self.oauth.reset();
$.each(oauthRes, function(k,v){
var resObj = v.split('=')
linkedInObj[resObj[0]] = resObj[1];
});
url = self.oauth.sign({action: "GET", path: "https://api.linkedin.com/v1/people/~/email-address", signatures: linkedInObj}).signed_url;
request = 'getResultLinkedIn';
linkedInWorkAround(url,request);
}
else if(request == 'getResultLinkedIn'){
$('body').css({opacity:0});
var userLIemail = ($('#session_key-oauthAuthorizeForm').size()) ? $('#session_key-oauthAuthorizeForm').val() : $(r).text();
}
},
error : function(a,b,c){
alert('err')
console.log(a,b,c)
self._cs(a)
$.mobile.loading( 'hide' );
if(a.statusText.toLowerCase() == 'unauthorized'){
$('.errMsgHolder').show().text('The email address or password you provided does not match our records');
}
}
})
}
linkedInWorkAround(url,request);

Related

Append antiforgery token to XMLHttpRequest

Pretty much what the title says. Here's the javascript... Works fine when not validating the token. Doesn't appear to see it when validating as I get The required anti-forgery form field "__RequestVerificationToken" is not present. error.
var downloadEmailSignature = function (control) {
if (control) {
let form = $(control).closest('form');
let token = $(form).find('input[name="__RequestVerificationToken"]').val();
if (form) {
let request = new XMLHttpRequest();
request.open("POST", "Forms/DownloadEmailSignature");
request.responseType = "blob";
request.setRequestHeader('RequestVerificationToken', token);
request.data = form.serialize();
request.onload = function () {
if (window.clientData.browser.name === "Internet Explorer") {
window.navigator.msSaveBlob(this.response, "EmailSignature.hta");
}
else{
let url = window.URL.createObjectURL(this.response);
let a = document.createElement("a");
document.body.appendChild(a);
a.href = url;
a.download = this.response.name || "download-" + $.now();
a.click();
}
};
console.dir(request);
request.send();
}
}
};
and the code behind...
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult DownloadEmailSignature(string emailSignature)
{
var hta = (MediaItem)SitecoreContext.GetItem<Item>(new Guid("{EE806F14-5BD3-491C-9169-DA701357FB45}"));
using (var reader = new StreamReader(MediaManager.GetMedia(hta).GetStream().Stream))
{
var htaText = reader.ReadToEnd();
htaText = htaText.Replace("*CARDSTRING*", emailSignature);
var stream = new MemoryStream(htaText.ToASCIIByteArray());
return new FileStreamResult(stream, "application/hta");
}
}
And finally the view...
<form id="download-email-signature" method="POST" enctype="multipart/form-data">
#Html.HiddenFor(m => m.EmailSignatureMarkup)
#Html.AntiForgeryToken()
#Html.FormIdentifier("FormsController", "DownloadEmailSignature")
Download installer
</form>
If you can replace XMLHttpRequest with $.ajax (as you already have JQuery loaded), the below segment should work.
let form = $(control).closest('form');
let token = $(form).find('input[name="__RequestVerificationToken"]').val();
$.ajax({
url: '/Home/DownloadEmailSignature',
type: 'POST',
data: {
__RequestVerificationToken: token,
emailSignature: 'emailSignature value'
},
success: function (result) {
alert(result);
//your code ....
}
});
According to the answer here:
ValidateAntiForgeryToken purpose, explanation and example
MVC's anti-forgery support writes a unique value to an HTTP-only
cookie and then the same value is written to the form. When the page
is submitted, an error is raised if the cookie value doesn't match the
form value.
Which implies the cookie MUST go back to the server. This should be working fine unless you are using IE9 (which is known to be problematic with this issue).
I recommend you include request.withCredentials = true; to eliminate any strange CORs related issue.
If a proxy is involved, the cookie may be getting stripped on the way back to the server too.

Change name of card on Trello with API by Javascript

I have this code in Javascript to modify the name of a Trello card through its API, and I do not get it, any ideas?
Documentation API Trello: https://developers.trello.com/v1.0/reference#cardsid-1
Code:
var onAuthorize = function() {
updateLoggedIn();
$("#output").empty();
Trello.members.get("me", function(member){
$("#fullName").text(member.fullName);
var id= "5ab7c3c631a2019c50b701c8";
//Change name
Trello.put('/boards/me/cards/5ab7c3c631a2019c50b701c8/name?value=nombrecito',function () {alert("funciona bien")}, function(err) {alert( "mal")});
});
};
var updateLoggedIn = function() {
var isLoggedIn = Trello.authorized();
$("#loggedout").toggle(!isLoggedIn);
$("#loggedin").toggle(isLoggedIn);
};
var logout = function() {
Trello.deauthorize();
updateLoggedIn();
};
Trello.authorize({
interactive:false,
success: onAuthorize
});
$("#connectLink")
.click(function(){
Trello.authorize({
type: "popup",
success: onAuthorize
})
});
$("#disconnect").click(logout);
The error I get is [object Object]
I have also tried with this URL:'cards/5ab7c3c631a2019c50b701c8/name?value=nombrecito'
It looks like your Trello.put URL is a little off.
Fix the Trello.put with...
Trello.put("/boards/mecards/5ab7c3c631a2019c50b701c8/name?value=nombrecito", function () {}, function(err) {alert(err)});
Have you tried the live example on the documentation page? It's not that complicated and something like this.
const API_KEY = 'your key';
const TOKEN = 'your token';
let id = 'your trello card id';
let newName = 'a new name what you want';
var data = null;
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
console.log(this.responseText);
}
});
xhr.open("PUT", "https://api.trello.com/1/cards/"+id+"?name="+newName+"&key="+API_KEY+"&token="+TOKEN);
xhr.send(data);
I've tested with my own cards and it works very well.

redirect_uri_mismatch error of google API while trying to login using c# asp.net

I need to login throw google in my page. I got my clientID and set the redirect_uri path in Google Console but when I am trying to login it is giving me the following error. I am integrating this on my asp.net page.
Error:
400. That’s an error.
Error: redirect_uri_mismatch
Application: odiyaDoctor
You can email the developer of this application at: odiyadoctor#gmail.com
The redirect URI in the request: http://localhost/immediateHelp.aspx did not match a registered redirect URI.
My requirement is when user will login by google on first page(UserLogin.aspx) and after successful login the next page(i.e.immediateHelp.aspx) will come. I am explaining my all code and google credentials below.
UserLogin.aspx:
</i>
<script>
var OAUTHURL = 'https://accounts.google.com/o/oauth2/auth?';
var VALIDURL = 'https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=';
var SCOPE = 'https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email';
var CLIENTID = '*************************g96b1elfa8.apps.googleusercontent.com';
var REDIRECT = 'http://localhost/immediateHelp.aspx';
var LOGOUT = 'http://accounts.google.com/Logout';
var TYPE = 'token';
var _url = OAUTHURL + 'scope=' + SCOPE + '&client_id=' + CLIENTID + '&redirect_uri=' + REDIRECT + '&response_type=' + TYPE;
var acToken;
var tokenType;
var expiresIn;
var user;
var loggedIn = false;
function googleLogin() {
var win = window.open(_url, "windowname1", 'width=800, height=600');
var pollTimer = window.setInterval(function () {
try {
console.log(win.document.URL);
if (win.document.URL.indexOf(REDIRECT) != -1) {
window.clearInterval(pollTimer);
var url = win.document.URL;
acToken = gup(url, 'access_token');
tokenType = gup(url, 'token_type');
expiresIn = gup(url, 'expires_in');
win.close();
validateToken(acToken);
}
} catch (e) {
console.log('its error', e);
}
}, 500);
}
function validateToken(token) {
$.ajax({
url: VALIDURL + token,
data: null,
success: function (responseText) {
getUserInfo();
loggedIn = true;
window.location.href = "immediateHelp.aspx";
},
dataType: "jsonp"
});
}
function getUserInfo() {
$.ajax({
url: 'https://www.googleapis.com/oauth2/v1/userinfo?access_token=' + acToken,
data: null,
success: function (resp) {
user = resp;
console.log('user info',user);
$('#imgHolder').attr('src', user.picture);
},
dataType: "jsonp"
});
}
function gup(url, name) {
name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
var regexS = "[\\#&]" + name + "=([^&#]*)";
var regex = new RegExp(regexS);
var results = regex.exec(url);
if (results == null)
return "";
else
return results[1];
}
</script>
In the above page the bellow error is coming in catch section.
at http://localhost:3440/UserLogin.aspx:92:32
UserLogin.aspx:103 its error DOMException: Blocked a frame with origin "http://localhost:3440" from accessing a cross-origin frame.
at Error (native)
clientID set in google.
Client ID for web application
Client ID
***************************************1ctsjaeg96b1elfa8.apps.googleusercontent.com
Client secret
*********oGbT13hv3S
Redirect URIs
https://localhost/immediateHelp.aspx
JavaScript origins
https://localhost
Here i need when user will logged in successfully,it will redirect to the immediateHelp.aspx page and in this page user can do the logout.Please help me to resolve these errors.
`"http://localhost/immediateHelp.aspx" != "https://localhost/immediateHelp.aspx"
The URL must be character perfect

Upload multiple photos in batch to Facebook using Javascript SDK

I can upload single photos via URL to Facebook, but I'm having trouble doing it using batch. I'm getting the (#324) Requires Upload File uncaught exception. I'm ensuring the user is logged in and when I look at the batch payload (batchJson) it looks okay.
To be clear, if I remove all the batch-related setup code and in the FB.api call replace "batch" : batchJson with a single "url": photoUrl the code works.
Here's my code. TIA for any insight on my error:
var message = $("#message-fb").val();
var batchItems = [];
var photoUrl = "";
$(".photo-selected").each(function () {
photoUrl = $(this).data('content');
item = {};
item['method'] = 'POST';
item['relative_url'] = 'me/photos';
item['url'] = encodeURI(photoUrl);
item['caption'] = message;
batchItems.push(item);
});
batchJson = JSON.stringify(batchItems);
alert(batchJson);
FB.getLoginStatus(function (response) {
if (response.status === 'connected') {
// Already logged in and authorized
FB.api(
"/",
"POST",
{
"batch": batchJson
},
function (response) {
if (response && !response.error) {
/* successful upload */
alert('Photos uploaded to Facebook (nl) - ' + JSON.stringify(response));
}
if (response && response.error) {
/* Provide error info during testing */
alert('Sorry, there was a problem uploading your photo to Facebook - ' + JSON.stringify(response));
}
});
} else {
// Need to login and authorize
FB.login(function () {
FB.api(
"/",
"POST",
{
'batch': batchJson
},
function (response) {
if (response && !response.error) {
/* successful upload */
alert('Photos uploaded to Facebook - ' + JSON.stringify(response));
}
if (response && response.error) {
/* Provide error info during testing */
alert('Sorry, there was a problem uploading your photo to Facebook - ' + JSON.stringify(response));
}
});
}, { scope: 'publish_actions' });
}
});
EDIT: Here are the relevant changes using #CBroe's answer:
$(".photo-selected").each(function () {
var photoUrl = $(this).data('content');
var item = {};
item['method'] = 'POST';
item['relative_url'] = 'me/photos';
var itemUrl = encodeURI(photoUrl);
var itemCaption = encodeURIComponent(message);
item['body'] = "caption=" + itemCaption + "&url=" + itemUrl;
batchItems.push(item);
});
batchJson = JSON.stringify(batchItems);
You are sending url and caption parameters on the same “level” as the method and relative_url – they need to be put inside a body property however. And the content of that field has to be encoded the same way an actual POST request via a form would be encoded (so like a URL query string, param1=value1&param2=value2).

How do I set a cookie in iOS Phonegap?

I'm using the reddit API and can successfully login and receive a cookie value in return. The code I use is as follows
loginPost = $.ajax({
type: 'POST',
url: 'http://www.reddit.com/api/login/' + username + '?user=' + username + '&passwd=' + password + '&api_type=json',
xhrFields: {
withCredentials: true
},
dataType: "json",
success: function() {
console.log("Define response variables");
var header = loginPost.getAllResponseHeaders();
var responseText = loginPost.responseText;
var match = header.match(/(Set-Cookie|set-cookie): reddit_session=(.+?);/);
if (match) {
reddit_session = match[2];
window.localStorage.setItem("reddit_session", reddit_session);
window.localStorage.setItem("reddit_username", username);
window.localStorage.setItem("reddit_password", password);
console.log("Logged in!");
//alert(responseText);
$('.loginWrapper').slideUp('fast', function() {
$('#feedWrapper').css("top", "44px");
$('#feedWrapper').css("bottom", "0");
// Animation complete.
});
}
else {
reddit_session = null;
window.localStorage.setItem("reddit_session", null);
navigator.notification.alert('Your username or password is incorrect. Please try again.');
console.log("Login Failed");
}
},
});
I am storing the cookie using
var header = loginPost.getAllResponseHeaders();
var match = header.match(/(Set-Cookie|set-cookie): reddit_session=(.+?);/);
if(match){
reddit_session = match[2];
window.localStorage.setItem("reddit_session", reddit_session);
But the cookie isn't sent with a simple request to http://www.reddit.com/api/me.json. All that is returned is an empty JSON response like this {}. If I browse to that link in my browser (and am, of course, logged into reddit) it returns a JSON string with all the user data.
Any idea how I can store the cookie so that it is usable in a UIWebView?
Any idea how I can store the cookie so that it is usable in a UIWebView?
It appears that iOS cookies have been problematic since phonegap 2.5; please see [Handling cookies in PhoneGap/Cordova
I can't see any more current (phonegap 3.3) info [http://docs.phonegap.com/en/3.3.0/_index.html]

Categories

Resources