How to connect with new Facebook C# SDK v5.0? - asp.net

I've been using the old v3.0 C# SDK for some time and Facebook have decided to deprecate that API and also block it so I can no longer use it. I'm trying to upgrading to v5.0 but it seems a lot more different and I can't get it to authenticate.
All I need is a Facebook login button which people click, login and allow permissions to my app (which works) but then I want to be able to call Get() on the C# SDK in the code behind to get their friends. This is what I have in my aspx page which works fine to allow them to login:
<input type="button" id="fblogin" value="Login to Facebook" disabled="disabled"/>
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
FB.init({
appId: 'myappid',
cookie: true,
xfbml: true,
oauth: true
});
function facebooklogin() {
FB.login(function(response) {
if (response.authResponse) {
// user authorized
// make sure to set the top.location instead of using
var accessToken = response.authResponse.accessToken;
window.location.reload();
} else {
// user cancelled
}
},
{
scope: 'publish_stream'
});
};
$(function() {
// make the button is only enabled after the facebook js sdk has been loaded.
$('#fblogin').attr('disabled', false).click(facebooklogin);
});
};
(function() {
var e = document.createElement('script'); e.async = true;
e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
document.getElementById('fb-root').appendChild(e);
} ());
However when I'm trying to connect to the Facebook client as below it throws an error which says
(OAuthException) An active access token must be used to query
information about the current user."} System.Exception
{Facebook.FacebookOAuthException}
FacebookClient client = new FacebookClient(myappid, mysecretkey)
SomeDictionary object = client.Get("/me/friends");
What am I missing to get this active authtoken? How can I access it in the code behind? Also what's the difference between using FacebookClient and FacebookWebClient?

In your web.config file you also have to set:
<facebookSettings appSecret="your app secret" appId="your app id" />
and to get the current user:
var facebookApp = new FacebookApp();
facebookApp.Api("/4");

Related

Fullcalendar + Private google calendar

I m using full calendar for a web app project and I sync it with google calendar of my client, but for the moment only public calendar.
Is there any way to sync with a private calendar ?
Note : We use 0auth to identify and sync with Google account.
Thanks
I think it would work with private calendar using the correct authorization.
Authorizing requests with OAuth 2.0
All requests to the Google Calendar API must be authorized by an authenticated user.
Here is a sample create by Alexandre:
<script type="text/javascript">
var clientId = '<your-client-id>';
var apiKey = '<your-api-key>';
var scopes = 'https://www.googleapis.com/auth/calendar';
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) {
var authorizeButton = document.getElementById('authorize-button');
if (authResult && !authResult.error) {
authorizeButton.style.visibility = 'hidden';
makeApiCall();
} else {
authorizeButton.style.visibility = '';
authorizeButton.onclick = handleAuthClick;
GeneratePublicCalendar();
}
}
function handleAuthClick(event) {
gapi.auth.authorize({client_id: clientId, scope: scopes, immediate: false}, handleAuthResult);
return false;
}
// Load the API and make an API call. Display the results on the screen.
function makeApiCall() {
// Step 4: Load the Google+ API
gapi.client.load('calendar', 'v3').then(function() {
// Step 5: Assemble the API request
var request = gapi.client.calendar.events.list({
'calendarId': '<your-calendar-id(The #gmail.com>'
});
// Step 6: Execute the API request
request.then(function(resp) {
var eventsList = [];
var successArgs;
var successRes;
if (resp.result.error) {
reportError('Google Calendar API: ' + data.error.message, data.error.errors);
}
else if (resp.result.items) {
$.each(resp.result.items, function(i, entry) {
var url = entry.htmlLink;
// make the URLs for each event show times in the correct timezone
//if (timezoneArg) {
// url = injectQsComponent(url, 'ctz=' + timezoneArg);
//}
eventsList.push({
id: entry.id,
title: entry.summary,
start: entry.start.dateTime || entry.start.date, // try timed. will fall back to all-day
end: entry.end.dateTime || entry.end.date, // same
url: url,
location: entry.location,
description: entry.description
});
});
// call the success handler(s) and allow it to return a new events array
successArgs = [ eventsList ].concat(Array.prototype.slice.call(arguments, 1)); // forward other jq args
successRes = $.fullCalendar.applyAll(true, this, successArgs);
if ($.isArray(successRes)) {
return successRes;
}
}
if(eventsList.length > 0)
{
// Here create your calendar but the events options is :
//fullcalendar.events: eventsList (Still looking for a methode that remove current event and fill with those news event without recreating the calendar.
}
return eventsList;
}, function(reason) {
console.log('Error: ' + reason.result.error.message);
});
});
}
function GeneratePublicCalendar(){
// You need a normal fullcalendar with googleApi when user isn't logged
$('#calendar').fullCalendar({
googleCalendarApiKey: '<your-key>',
...
});
}
</script>
<script src="https://apis.google.com/js/client.js?onload=handleClientLoad"></script>
Or
Perform Google Apps Domain-Wide Delegation of Authority
In enterprise applications you may want to programmatically access users data without any manual authorization on their part. In Google Apps domains, the domain administrator can grant to third party applications domain-wide access to its users' data — this is referred as domain-wide delegation of authority. To delegate authority this way, domain administrators can use service accounts with OAuth 2.0.
For additional detailed information, see Using OAuth 2.0 for Server to Server Applications
Hope this helps!
I have tried in the backend with php, use the google php client library to get the events and then put it into fullcalendar. This way, it works.

Incorrect path to SignalR generated on client

So I have been plugging away trying to get SignalR to work with my Web Api instance that used OWIN and authentication. After figuring out CORS (thanks to SO help) I am almost there.
My web client fails with a Javascript error on the console.
http://localhost:45325/negotiate?clientProtocol=1.5&connectionData=%5B%7B%22name%22%3A%22myhub%22%7D%5D&_=1460577212205 404 (Not Found)
if I take this URL and put it in the browser sure enough I get a 404 error. However if I add /signalr/ to the path as such ...
http://localhost:45325/signalr/negotiate?clientProtocol=1.5&connectionData=%5B%7B%22name%22%3A%22myhub%22%7D%5D&_=1460577212205
I get a proper JSON response with the SignalR connectionid and everything ...
{
"Url": "/signalr",
"ConnectionToken": "<token here>",
"ConnectionId": "0bf84c7a-0a28-4da9-bb9f-551de894cf0e",
"KeepAliveTimeout": 20,
"DisconnectTimeout": 30,
"ConnectionTimeout": 110,
"TryWebSockets": true,
"ProtocolVersion": "1.5",
"TransportConnectTimeout": 5,
"LongPollDelay": 0
}
So it looks as though everything is working other than the fact that the URL the client is generating to connect to the SignalR hub is missing the /signalr.
Here is my client side Javascript that connects to the Hub. Where can I specify the path needs to include /signalr? Because I thought I already was ...
<script src="scripts/jquery-2.2.2.min.js"></script>
<script src="scripts/jquery.signalR-2.2.0.js"></script>
<script>
(function ($) {
$(function () {
var connection = $.hubConnection('/signalr/', {useDefaultPath: false});
var myHubProxy = connection.createHubProxy('MyHub');
myHubProxy.on('notify', function (username) {
console.log(username + ' has logged in');
alert(username + ' has logged in');
});
connection.url = 'http://localhost:45325';
connection.start()
.done(function() {
alert('Connected to MyHub: Connection ID = ' + connection.id);
})
.fail(function(e) {
console.log('Connection error: ' + e);
});
});
})(jQuery);
</script>
You may notice that I did not include <script src="signalr/hubs"></script>. This is because I am created the proxy myself instead of relying on the auto-generated proxy
I figured it out! It should have been obvious to me ...
In my Javascript on the client I needed to add the \signalr path ...
connection.url = 'http://localhost:45325/signalr';
Perhaps I should have seen that in my public void Configuration(IAppBuilder) method inside the Startup.cs class of my Web Api I had the following ..
app.Map("/signalr", map =>
{
map.UseCors(CorsOptions.AllowAll);
var hubConfiguration = new HubConfiguration
{
// EnableJSONP = true; // I am not using as CORS is working just fine
};
map.RunSignalR(hubConfiguration);
});
I was specifying the subdirectory "/signalr"

FullCalendar with private google calendar event

I currently using google calendar on my website with the iframe you can insert. I tested Fullcalendar and I like what you can do with it.
But I would like to do same as the embed calendar, I would like to be able to create private event (not calendar, events). The sharing settings of the calendar is on public, but when using chrome, you can log with your google account and with the embed calendar you can see private event (if you have access to the calendar).
Is that possible with Fullcalendar ?
I figure out how to connect via OAUTH and get the private event when you are authentified.
By clicking on a button, you can connect to a google account (If already connected in browser, no button will appear and you will be log automaticly).
I follow this google example
<script type="text/javascript">
var clientId = '<your-client-id>';
var apiKey = '<your-api-key>';
var scopes = 'https://www.googleapis.com/auth/calendar';
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) {
var authorizeButton = document.getElementById('authorize-button');
if (authResult && !authResult.error) {
authorizeButton.style.visibility = 'hidden';
makeApiCall();
} else {
authorizeButton.style.visibility = '';
authorizeButton.onclick = handleAuthClick;
GeneratePublicCalendar();
}
}
function handleAuthClick(event) {
gapi.auth.authorize({client_id: clientId, scope: scopes, immediate: false}, handleAuthResult);
return false;
}
// Load the API and make an API call. Display the results on the screen.
function makeApiCall() {
// Step 4: Load the Google+ API
gapi.client.load('calendar', 'v3').then(function() {
// Step 5: Assemble the API request
var request = gapi.client.calendar.events.list({
'calendarId': '<your-calendar-id(The #gmail.com>'
});
// Step 6: Execute the API request
request.then(function(resp) {
var eventsList = [];
var successArgs;
var successRes;
if (resp.result.error) {
reportError('Google Calendar API: ' + data.error.message, data.error.errors);
}
else if (resp.result.items) {
$.each(resp.result.items, function(i, entry) {
var url = entry.htmlLink;
// make the URLs for each event show times in the correct timezone
//if (timezoneArg) {
// url = injectQsComponent(url, 'ctz=' + timezoneArg);
//}
eventsList.push({
id: entry.id,
title: entry.summary,
start: entry.start.dateTime || entry.start.date, // try timed. will fall back to all-day
end: entry.end.dateTime || entry.end.date, // same
url: url,
location: entry.location,
description: entry.description
});
});
// call the success handler(s) and allow it to return a new events array
successArgs = [ eventsList ].concat(Array.prototype.slice.call(arguments, 1)); // forward other jq args
successRes = $.fullCalendar.applyAll(true, this, successArgs);
if ($.isArray(successRes)) {
return successRes;
}
}
if(eventsList.length > 0)
{
// Here create your calendar but the events options is :
//fullcalendar.events: eventsList (Still looking for a methode that remove current event and fill with those news event without recreating the calendar.
}
return eventsList;
}, function(reason) {
console.log('Error: ' + reason.result.error.message);
});
});
}
function GeneratePublicCalendar(){
// You need a normal fullcalendar with googleApi when user isn't logged
$('#calendar').fullCalendar({
googleCalendarApiKey: '<your-key>',
...
});
}
</script>
<script src="https://apis.google.com/js/client.js?onload=handleClientLoad"></script>
And in your google api console, make sure in API & Auth -> ID
OAuth Javascript origin is set properly (Like http://localhost
https://localhost if you are working on a local website)
Leave Redirection and API referent empty.
Fullcalendar is a front-end solution only. Logging into a google account and any other authentication isn't part of it.
That said, it can be connected to a google calendar, but only if it's a public google calendar. If you want to interface it to a private google calendar, you would have to build in that functionality.
If you can get the gcal events with JS and handle authentication, getting them into FullCalendar is easy. But that first part takes a few steps. Take a look at the google calendar api docs for instruction.

Facebook C# SDK Login in Sandbox Mode Http vs Https

I have created an application using c# SDK.
The canvas page http://mywebsite/ is working fine and I made to accomplish what the client wants, but when i try to access the application via https://apps.facebook.com/ApplicationName which creates an iframe to http://mywebsite/, the login gets stuck.
This is what appears when I hit connect:
That is the permissions window, the permissions appear, I hit ok, and nothing happens.
Code:
<div id="fb-root"></div>
<script type="text/javascript">
window.fbAsyncInit = function () {
// alert("aqui estoy");
FB.init({
appId: '397613493644598', // App ID
status: true, // check login status
cookie: true, // enable cookies to allow the server to access the session
xfbml: true // parse XFBML
});
FB.Event.subscribe('auth.authResponseChange', function (response) {
if (response.status === 'connected') {
// the user is logged in and has authenticated your
// app, and response.authResponse supplies
// the user's ID, a valid access token, a signed
// request, and the time the access token
// and signed request each expire
var uid = response.authResponse.userID;
var accessToken = response.authResponse.accessToken;
//alert("conectado");
// Do a post to the server to finish the logon
// This is a form post since we don't want to use AJAX
var form = document.createElement("form");
form.setAttribute("method", 'post');
form.setAttribute("action", '/Home/Login');
var field = document.createElement("input");
field.setAttribute("type", "hidden");
field.setAttribute("name", 'accessToken');
field.setAttribute("value", accessToken);
form.appendChild(field);
document.body.appendChild(form);
form.submit();
} else if (response.status === 'not_authorized') {
alert("Not Authorized");
// the user is logged in to Facebook,
// but has not authenticated your app
} else {
alert("Not logged In");
// the user isn't logged in to Facebook.
}
});
};
// Load the SDK Asynchronously
(function (d) {
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) { return; }
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
} (document));
</script>
<fb:login-button perms="user_birthday,email"> Connect</fb:login-button>
I may know what the problem is, but I need confirmation.
Does the problem is that facebook apps address is https and my app canva url is http?,
Found the answer, if you are testing stage, and this happens to you, you can do the following action.
Go to this link https://www.facebook.com/settings?tab=security
And disable secure browsing (this is just while you publish your app). Then your app should work fine.
Once you are ready to buy a certificate, and publish your application, Enable again this feature.
So the answer to my question:
Does the problem is that facebook apps address is https and my app canva url is http?,
is YES

Facebook Connect Asp.net C# Request Cookies Returning Null

I was able to login into my website and successfully register new user using facebook connect and get the user information.
But, all of a sudden it stopped working.
code on the aspx page
<div id="fb-root"></div></form>
<script>
window.fbAsyncInit = function () {
FB.init({
appId: '147340123456789', // App ID
channelUrl: '', // Channel File
status: true, // check login status
cookie: true, // enable cookies to allow the server to access the session
xfbml: true // parse XFBML
});
// Additional initialization code here
};
// Load the SDK Asynchronously
(function (d) {
var js, id = 'facebook-jssdk'; if (d.getElementById(id)) { return; }
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
d.getElementsByTagName('head')[0].appendChild(js);
} (document));
It appears all of the code that does login is missing from that page. Check your source control for a previous version.

Resources