I am using the following code in my facebook application. The when loading the application in facebook has no problem in chrome/firefox/ie8. When it runs in IE9 it is reporting that OAuthException has been thrown.
public string GetFacebookId() {
if (!FacebookWebContext.Current.IsAuthorized())
return string.Empty;
var client = new FacebookWebClient();
dynamic me = client.Get("me");
return me.id;
}
(OAuthException) An active access token must be used to query
information about the current user.
any suggestions would be appreciated.
thanks.
EDIT:
window.fbAsyncInit = function () {
FB.init({
appId: '#(Facebook.FacebookApplication.Current.AppId)', // App ID
//channelURL: '//facebook.thefarmdigital.com.au/moccona/premium/FacebookChannel/', // Channel File
status: true, // check login status
cookie: true, // enable cookies to allow the server to access the session
oauth: true, // enable OAuth 2.0
xfbml: true // parse XFBML
});
FB.Canvas.setAutoGrow();
};
$(function () {
$('#custom_login').click(function () {
FB.getLoginStatus(function (response) {
if (response.authResponse) {
//should never get here as controller will pass to logged in page
} else {
FB.login(function (response) {
if (response.authResponse) {
window.location = '#(Request.Url.AbsoluteUri.Replace(Request.Url.PathAndQuery, ""))' + $('#custom_login').attr('href');
} else {
window.location = '#(Request.Url.AbsoluteUri.Replace(Request.Url.PathAndQuery, ""))' + $('#custom_login').attr('dataFail');
}
}, { scope: 'publish_stream' });
}
});
return false;
});
});
I'm not familiar with FB's C# SDK, but judging from the code you gave, it does not seem that you are doing any user authentication with FB. It might be that it works in Chrome and Firefox only because you are somehow already logged into your FB app in those browsers.
Related
I have created a bot with MS Bot SDK. Then, I want to get the page URL where I'm hosting the bot. I just inject the script to a page to host the bot. But, does anyone who knows how to get the current page URL from C#?
I can see someone is trying to use Activity for getting the URL, but I can't find the right property from Activity.
I just inject the script to a page to host the bot. But, does anyone who knows how to get the current page URL from C#?
If you embed webchat in your web site and you want to get the URL of the web page where you embed the webchat, you can try the following approach to get the URL and pass it to your bot.
Pass the URL to bot:
<script>
var urlref = window.location.href;
BotChat.App({
directLine: { secret: "{directline_secret}" },
user: { id: 'You', pageurl: urlref},
bot: { id: '{bot_id}' },
resize: 'detect'
}, document.getElementById("bot"));
</script>
Retrieve the URL in bot application:
if (activity.From.Properties["pageurl"] != null)
{
var urlref= activity.From.Properties["pageurl"].ToString();
}
ChannelData was designed to enable sending custom information from client to bot, and back. Similar to Fei Han's answer, you can intercept outgoing messages and provide custom ChannelData for every activity sent.
<script>
var dl = new BotChat.DirectLine({
secret: 'yourdlsecret',
webSocket: false,
pollingInterval: 1000,
});
var urlref = window.location.href;
BotChat.App({
botConnection: {
...dl,
postActivity: activity => dl.postActivity({
...activity,
channelData: { pageurl: urlref }
})
},
user: { id: 'userid' },
bot: { id: 'botid' },
resize: 'detect'
}, document.getElementById("bot"));
</script>
Then, in the bot:
I'm using PayPal express checkout (checkout.js V4.0.0) with asp.net mvc to allow a user to pay for data transactions. What I need to do when the express checkout button is clicked is perform some checks on the database and confirm that PayPal can proceed (this is also time related, as the database could be in a locked processing state).
I've setup the Advanced Server Integration and I then call the create-payment controller from the payment section in paypal.Button.render, but this expects a json object with a PaymentID element to be returned. At what point am I able to perform these checks on server side and abort from the paypal process if PayPal can't continue? If a check fails, the server side also needs to return an appropriate error page or message to be displayed.
This is the paypal button code:
<script src="https://www.paypalobjects.com/api/checkout.js"></script>
<script>
paypal.Button.render({
env: 'sandbox',
payment: function (resolve, reject) {
var CREATE_PAYMENT_URL = '#Url.Action("PayTransactions","Pending")';
paypal.request.post(CREATE_PAYMENT_URL)
.then(function (data) { resolve(data.paymentID); })
.catch(function (err) { reject(err); });
},
onAuthorize: function(data) {
var EXECUTE_PAYMENT_URL = 'https://my-store.com/paypal/execute-payment';
paypal.request.post(EXECUTE_PAYMENT_URL,
{
paymentID: data.paymentID,
payerID: data.payerID
})
.then(function(data) { /* Go to a success page */ })
.catch(function (err) { /* Go to an error page */ });
},
onCancel: function (data, actions) {
return actions.redirect();
},
onError: function (err) {
// Show an error page here, when an error occurs
}
}, '#paypal-button');
</script>
which at the payment section calls this:
public async Task<string> PayTransactions()
{
// check if payment is still necessary or end of month is running
var condition = await CheckDatabaseIsUsable();
switch (condition)
{
case 1:
ModelState.AddModelError("error", "some error message");
return RedirectToAction("Index", "Pending");
case 2:
ModelState.AddModelError("error", "some other error");
return RedirectToAction("Index", "Pending");
}
var paypalPayment = FormPayPalPaymentObject();
return JsonConvert.SerializeObject(new { paymentID = paypalPayment.PaymentId });
}
The problem is that I am now mixing the ActionResult and json string return types.
You can return json also for the redirection responses and control with javascript when it is a redirection or and ok response.
Server side:
return JsonConvert.SerializeObject(new { redirect= Url.Action("Index", "Pending") });
Javascript:
paypal.request.post(CREATE_PAYMENT_URL)
.then(function (data) {
if(data.redirect)
{
//cancel the flow and redirect if needed
window.location.href = data.redirect;
}else{
resolve(data.paymentID);
}
})
.catch(function (err) { reject(err); });
},
Using an IActionResult object as the return value for the PayTransactions is preferable
public async Task<IActionResult> PayTransactions()
{
...
return Json(new { paymentID = paypalPayment.PaymentId });
}
Also consider that the modelstate errors you are adding are useless because of the redirection.
You can call reject(error) to cancel the payment.
On a mobile app, I want to have a Share button that posts an image on behalf of the user, but instead of posting it on this user's timeline, it must be posted on a specific Facebook Page timeline.
By using the Share dialog, it seems there is no way to configure the target of the post (in this case, the Facebook Page). Or at least I couldn't find it.
How would you do it?
Note: the app is made in Unity/C#, although I don't think this would matter much
Try this code :)
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
FB.init({
appId : '**appId**',
channelUrl : '//local.facebook-test/channel.html',
status : true,
xfbml : true,
oauth : true
});
FB.login(function(response)
{
if (response.authResponse)
{
var opts = {
message : '**message**',
access_token: '**PageAccessToken**',
name : '**name**',
link : 'https://developers.facebook.com/docs/reference/dialogs/',
description : '**description**',
picture : 'http://url/to/pic.jpg'
};
FB.api('/me/feed', 'post', opts, function(response)
{
if (!response || response.error)
{
console.log(response.error);
alert('Posting error occured');
}else{
alert('Success - Post ID: ' + response.id);
}
});
} else {
alert('Not logged in');
}
}, { scope: 'manage_pages, publish_actions, user_photos' });
};
(function (d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) { return; }
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/all.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
</script>
I know this is duplicate but I could not get reliable solution(for asp.net web).
I just want to redirect to the login page if session expires.
I have tried following:
1. using jquery status code
$.ajax({
type: "POST",
url: "stream.asmx/SomeMethod",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
//success msg
},
error: function (request, status, error) {
if (status = 403) {
location.href = 'login.aspx';
}
}
});
Problem: this returns same status code(403) for other errors too, which I only expect for session timeout.
2. Sending json message whether session expired
code behind:
if (!object.Equals(HttpContext.Current.Session["User"], null))
{
Id = int.Parse(HttpContext.Current.Session["User"].ToString());
}
else
{
result = from row in dtscrab.AsEnumerable()
select new
{
redirectUrl = "login.aspx",
isRedirect = true
};
}
on $.ajax success:
success: function (msg) {
if (msg.d[0].isRedirect) {
window.location.href = msg.d[0].redirectUrl;
}
else {
//load containt
}
}
Problem: It's somehow desn't invoke ajax success line if session expires(it does return correct json). And even this is not a proper way if I have many number of ajax request in the page(should be handled globally).
However, I saw this post which is really good soltion but it's for mvc using AuthorizeAttribute: handling-session-timeout-in-ajax-calls
So, Is there I can use same concept used in mvc using AuthorizeAttribute in asp.net web api? If not, how I can troubleshoot those issue which I'm facing (any of above two mentioned)?
A 403 status code is going to cause jQuery to call the failure method. Keep the same code behind from your second try, but move the redirect handler to the failure method instead of the success method. In the success method, treat it as you normally would.
Problem:
I had same problem in my Razor MVC Application throwing exceptions while ajax calls made when session timed out.
The way I have managed to get this issue sorted is by monitoring each ajax requests by using a simple light weight Action Method (RAZOR MVC) returning a bool variable whether the Request is Authenticated or not. Please find the code below..
Layout/Master Page / Script file:
<script>
var AuthenticationUrl = '/Home/GetRequestAuthentication';
var RedirectUrl = '/Account/Logon';
function SetAuthenticationURL(url) {
AuthenticationUrl = url;
}
function RedirectToLoginPage() {
window.location = RedirectUrl;
}
$(document).ajaxStart(function () {
$.ajax({
url: AuthenticationUrl,
type: "GET",
success: function (result) {
if (result == false) {
alert("Your Session has expired.Please wait while redirecting you to login page.");
setTimeout('RedirectToLoginPage()', 1000);
}
},
error: function (data) { debugger; }
});
})
Then in Home Controller/Server side you need a method to verify the request and return the boolean variable..
public ActionResult GetAuthentication ( )
{
return Json(Request.IsAuthenticated, JsonRequestBehavior.AllowGet);
}
This will validate each ajax request and if the session got expired for any ajax request, it will alert the user with a message and redirect the user to the login page.
I would also suggest not to use standard Alert to Alert. User some Tool tip kind of formatted div Alerts. Standard JS Alerts might force the user to click OK before redirection.
Hope it helps.. :)
Thanks,
Riyaz
Finally, I ended up following.
public class IsAuthorizedAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
var sessions = filterContext.HttpContext.Session;
if (sessions["User"] != null)
{
return;
}
else
{
filterContext.Result = new JsonResult
{
Data = new
{
status = "401"
},
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
//xhr status code 401 to redirect
filterContext.HttpContext.Response.StatusCode = 401;
return;
}
}
var session = filterContext.HttpContext.Session;
if (session["User"] != null)
return;
//Redirect to login page.
var redirectTarget = new RouteValueDictionary { { "action", "LogOn" }, { "controller", "Account" } };
filterContext.Result = new RedirectToRouteResult(redirectTarget);
}
}
Handling client side
<script type="text/javascript">
$(document).ajaxComplete(
function (event, xhr, settings) {
if (xhr.status == 401) {
window.location.href = "/Account/LogOn";
}
});
</script>
you can set session time out expire warning some thing like ....
<script type="text/javascript">
//get a hold of the timers
var iddleTimeoutWarning = null;
var iddleTimeout = null;
//this function will automatically be called by ASP.NET AJAX when page is loaded and partial postbacks complete
function pageLoad() {
//clear out any old timers from previous postbacks
if (iddleTimeoutWarning != null)
clearTimeout(iddleTimeoutWarning);
if (iddleTimeout != null)
clearTimeout(iddleTimeout);
//read time from web.config
var millisecTimeOutWarning = <%= int.Parse(System.Configuration.ConfigurationManager.AppSettings["SessionTimeoutWarning"]) * 60 * 1000 %>;
var millisecTimeOut = <%= int.Parse(System.Configuration.ConfigurationManager.AppSettings["SessionTimeout"]) * 60 * 1000 %>;
//set a timeout to display warning if user has been inactive
iddleTimeoutWarning = setTimeout("DisplayIddleWarning()", millisecTimeOutWarning);
iddleTimeout = setTimeout("TimeoutPage()", millisecTimeOut);
}
function DisplayIddleWarning() {
alert("Your session is about to expire due to inactivity.");
}
function TimeoutPage() {
//refresh page for this sample, we could redirect to another page that has code to clear out session variables
location.reload();
}
4xx are HTTP error status codes and would cause jquery to execute the onFailure callback.
Also, beware of using 3xx for redirects when you want to process the payload. Internet Explorer, in my experience, just does a redirect (without looking at the payload) when a 3xx status code is returned.
I'd say, throw a 403 and handle the situation. To the client 403 implies the resource access is forbidden. There can be multiple reasons, which is OK I guess.
For those using a ScriptManager, you can easily check for ajax request and then redirect with the following code:
private void AjaxRedirect(string url)
{
Response.StatusCode = 200;
Response.RedirectLocation = url;
Response.Write("<html></html>");
Response.End();
}
Then check for request type and redirect accordingly (using routes here):
if (ScriptManager.GetCurrent(Page).IsInAsyncPostBack)
{
var redirectUrl = RouteTable.Routes.GetVirtualPath(null, "Default", null).VirtualPath;
AjaxRedirect(redirectUrl);
}
else
{
Response.RedirectToRoute("Default");
}
The "Default" route is a route defined in the routes collection:
routes.MapPageRouteWithName("Default", "", "~/default.aspx");
If you prefer, instead of using ScriptManager for ajax request check, you can use:
if (Request.Headers["X-Requested-With"] == "XMLHttpRequest") {
code here...
}
am trying to validate the recaptcha using some js code but am getting some permission Errors "Access is Denied"
Is it possible to achieve the validation using the javascript validation code alongside ajax across multiple browsers.
<script type="text/javascript">
$(document).ready(function() {
Recaptcha.create("var_public_key", recaptchadiv, {
theme: "clean",
callback: Recaptcha.focus_response_field
});
});
function submitFormData() {
var urlString = "http://www.google.com/recaptcha/api/verify";
var params = encodeURI("remoteip=" + $("#userIp").val() +"&privatekey=" + var_private_key + "&challenge=" + Recaptcha.get_challenge() + "&response=" +
Recaptcha.get_response());
params = encodeURI(params);
var status = document.getElementById("status");
status.className = "";
status.innerHTML = "<b>Submitting your data. Please wait...</b>";
var html = $.ajax({
type: "POST",
url: urlString + "?" + params,
async: false
}).responseText;
alert("ResponseText: " + html + ", Recaptcha.responseText: " + Recaptcha.responseText);
var result = html.split("\n")[0];
if (result == "true") {
status.innerHTML = " ";
return true;
}
else {
status.className = "GlobalErrorText";
status.innerHTML = "Your captcha is incorrect. Please try again";
Recaptcha.reload();
return false;
}
}
</script>
#Boug is right, this is called cross site ajax request, you can see this question to see if you can a find a solution Cross-site AJAX requests but....
I think putting your private key for recaptcha in javascript is a vulnerability, recaptcha should be validated on Server Side code, this question contain useful links about how to implement recaptcha in Asp.Net MVC How to implement reCaptcha for ASP.NET MVC? I used this approach and it works perfectly http://www.dotnetcurry.com/ShowArticle.aspx?ID=611&AspxAutoDetectCookieSupport=1
You are getting permission error because your ajax code is trying to access a script on a different site (google) as your script. From what I know, I dont think you can do cross site Ajax calls for security reasons
The question has already been answered. But, here's some added code that will work in ASP.NET WebForms, which enables you to make a local AJAX request to the page w/ the reCaptcha control, then do server-side captcha validation. The page's web method will return true/false.
I got this code from mindfire solutions, but added the execution of JS functions in the Ajax success callback b/c Ajax is making async callbacks.
Javascript:
<script type="text/javascript">
$(function(e) {
$("#submit").click(function() { // my button is type=button, not type=submit
// I'm using jQuery validation and want to make sure page is valid before making Ajax request
if ( $("#aspnetForm").valid() ) {
validateCaptcha(); // or validateCaptchaJson() if you want to use Json
} // end If ($("#aspnetForm").valid())
}); // end $("#submit").click()
}); // end $(function(e)
function validateCaptcha() {
// Individual string variables storing captcha values
var challengeField = $("input#recaptcha_challenge_field").val();
var responseField = $("input#recaptcha_response_field").val();
// Ajax post to page web method that will do server-side captcha validation
$.ajax({
type: "POST",
url: "page.aspx/ValidateCaptcha",
data: "recaptcha_challenge_field=" + challengeField + "&recaptcha_response_field=" + responseField,
async: false
success: function(msg) {
if(msg.d) { // Either true or false, true indicates CAPTCHA is validated successfully.
// this could hide your captcha widget
$("#recaptcha_widget_div").html(" ");
// execute some JS function upon successful captcha validation
goodCaptcha();
} else {
// execute some JS function upon failed captcha validation (like throwing up a modal indicating failed attempt)
badCaptcha();
// don't forget to reload/reset the captcha to try again
Recaptcha.reload();
}
return false;
}
});
}
function validateCaptchaJson() {
// JavaScript object storing captcha values
var captchaInfo = {
challengeValue: Recaptcha.get_challenge(),
responseValue: Recaptcha.get_response()
};
// Ajax post to page web method that will do server-side captcha validation
$.ajax({
type: "POST",
url: "page.aspx/ValidateCaptcha",
data: JSON.stringify(captchaInfo), // requires ref to JSON (http://www.JSON.org/json2.js)
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function(msg) {
if(msg.d) { // Either true or false, true indicates CAPTCHA is validated successfully.
// this could hide your captcha widget
$("#recaptcha_widget_div").html(" ");
// execute some JS function upon successful captcha validation
goodCaptcha();
} else {
// execute some JS function upon failed captcha validation (like throwing up a modal indicating failed attempt)
badCaptcha();
// don't forget to reload/reset the captcha to try again
Recaptcha.reload();
}
return false;
}
});
}
</script>
Page's Web Method (VB.NET):
<WebMethod()> _
Public Shared Function ValidateCaptcha(ByVal challengeValue As String, ByVal responseValue As String) As Boolean
' IDEA: Get Private key of the CAPTCHA from Web.config file.
Dim captchaValidtor As New Recaptcha.RecaptchaValidator() With { _
.PrivateKey = "your_private_key_goes_here", _
.RemoteIP = HttpContext.Current.Request.UserHostAddress, _
.Challenge = challengeValue, _
.Response = responseValue _
}
' Send data about captcha validation to reCAPTCHA site.
Dim recaptchaResponse As Recaptcha.RecaptchaResponse = captchaValidtor.Validate()
' Get boolean value about Captcha success / failure.
Return recaptchaResponse.IsValid
End Function