Update and solution: It turns out the problem was based on a redirect I used for my dev URL, which resulted in browsers perceiving all cookies set by my page as third-party cookies. The Facebook JS API session cookie is not set as a third-party cookie.
I'm working on an ASP.NET application with Facebook authentication. For this I use Microsofts Facebook SDK in combination with Facebooks Javascript API. Everything's working, except for Safari. Safaris default setting is to not accept third-party cookies, which results in:
I can access the Facebook session through Javascript.
I can NOT access the Facebook session server-side, because the cookie is never set and sent from Safari.
This is my client-side code related to Facebook (JS):
<div id="fb-root"></div>
<fb:login-button>Login with Facebook</fb:login-button>
<script src="http://connect.facebook.net/en_US/all.js"></script>
<script>
FB.init({ appId: 'myAppId', status: true, cookie: true, xfbml: true });
FB.Event.subscribe('auth.login', function (response) {
if (response.session) {
window.location.reload(); //Results in eternal reload of page
}
});
</script>
This is my code for fetching the user id server-side (C#):
public string FacebookUserID
{
get
{
FacebookSettings settings = new FacebookSettings();
settings.AppId = "myAppId";
settings.AppSecret = "myAppSecret";
FacebookApp app = new FacebookApp(settings);
Authorizer auth = new Authorizer(app);
return (auth.IsAuthorized()) ? app.Session.UserId : null;
}
}
I guess I'm not the only one with the same problem, but I've searched both the Facebook Developer forum and here and haven't found a solution. It's really more of a Safari problem than a Facebook-specific problem.
I've been thinking about posting the user-id back to the server through GET/POST/my own cookie, but that is an ugly solution and a potential security issue.
Any ideas?
It turns out the problem was based on a redirect I used for my dev URL, which resulted in browsers perceiving all cookies set by my page as third-party cookies. The Facebook JS API session cookie is not set as a third-party cookie.
Related
working on a .NET MAUI app and am trying to implement Firebase Authentication with the help of WebAuthenticator in MAUI. I get to the login form in a browser, but after logging in get the error
Unable to process request due to missing initial state. This may happen if browser sessionStorage is inaccessible or accidentally cleared.
This is the code that calls the authenticator
await client.SignInWithRedirectAsync(FirebaseProviderType.Google, async uri =>
{
var options = new WebAuthenticatorOptions
{
Url = new Uri(uri),
CallbackUrl = new Uri("com.companyname.myappname://callback/"),
PrefersEphemeralWebBrowserSession= true
};
var res = await WebAuthenticator.Default.AuthenticateAsync(options);
});
I think the problem could be the callback URL, but I'm not sure how to write it differently since I'm not using a backend API. Does anyone have any suggestions?
Thanks!
P.S. This happens with bost Firebase Google auth and Facebook login
You can try to clear the chrome browser data and reload the page to see if it works. This is a known problem of firebase. You can continue to follow up this github iissue: Unableto process request due to missing initial state.
Is it possible?
I read a bit on https://firebase.google.com/docs/auth/web/phone-auth but it mentions OAuth redirect domains all the time, not sure if chrome extension domains are valid for this?
They don't work in a chrome extension, but you could render the reCAPTCHA verifier in a web page, get the verification ID and code and pass it to your chrome extension using something like postMessage and then sign in through your chrome extension as:
// You get verificationId from reCAPTCHA rendered on web page.
// You ask the user to provide the 6 digit code.
var cred = firebase.auth.PhoneAuthProvider.credential(verificationId, code);
firebase.auth().signInWithCredential(cred)
.then(function(result) {
// User signed in.
})
.catch(function(error) {
// Error occurred.
});
Problem: When used via 3rd-party app built-in browser (e.g. LINE, Twitter or Facebook messenger), the signInWithPopup returns auth/popup-blocked. The explanation by Firebase docs is:
auth/popup-blocked: Thrown if the popup was blocked by the browser, typically when this operation is triggered outside of a click handler.
Typical sequence triggering this error is: Link of my web app is sent to LINE, Twitter or Facebook messenger. When user uses mobile device and opens that link in those apps, their built-in browser is opened. Calling signInWithPopup then returns the error. The behavior is slightly different in iOS and Android but at least iOS/LINE combination results the error.
I am using Angular and building a web app. The error message is Unable to establish a connection with the popup. It may have been blocked by the browser. which comes from the firebase.js - not my own text.
When used in a normal browser, the signup works just fine.
Any ideas why the built-in browsers and signInWithPopup do not work together?
Firebase authentication should start with some user interaction, such as click on button. This solved the problem for me.
Many in-app embedded browsers block popups. I ran into the issue on instagram. Try using signInWithRedirect instead of signInWithPopup when kicking off the Oauth call.
Firebase documentation on usage of both methods can be found here - https://firebase.google.com/docs/reference/js/firebase.auth.Auth#signInWithPopup
signInWithPopup() is for the browser, however, if you're running iOS or Andriod emulator or device, you need to call signInWithCredential.
signInWithFacebook() {
if (this.platform.is('cordova')) {
return this.fb.login(['email', 'public_profile']).then(res => {
const facebookCredential = firebase.auth.FacebookAuthProvider.credential(res.authResponse.accessToken);
return firebase.auth().signInWithCredential(facebookCredential);
})
}
else {
return this.afAuth.auth
.signInWithPopup(new firebase.auth.FacebookAuthProvider())
.then(res => console.log(res));
}
}
If you're using Ionic + Firebase, you can find more info here
I have the same issue, with my web app on facebook ads campaign. I change my code from popup to redirect.
googleAuth() {
firebase
.auth()
.getRedirectResult()
.then(function(result) {
this.showLoading = true;
if (result.credential) {
var token = result.credential.accessToken;
console.log(token);
}
var user = result.user;
console.log(user);
});
this.showLoading = true;
const provider = new firebase.auth.GoogleAuthProvider();
provider.addScope("profile");
provider.addScope("email");
firebase.auth().signInWithRedirect(provider);
}
}
The problem now is save my utms from campaigns, because with redirect you lose them.
There seems to be a bug with the LinkedIn JS SDK. You're able to reproduce with the code they supply in the "Getting Started" section of the docs.
<!DOCTYPE html>
<html>
<head>
<title>LinkedIn test</title>
<script>
// 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>
<script type="text/javascript" src="//platform.linkedin.com/in.js">
api_key: [API_KEY]
onLoad: onLinkedInLoad
</script>
</head>
<body>
<script type="in/Login"></script>
</body>
</html>
If you put this code on a non-https site and hit that URL on iOS Safari, clicking the "sign in with LinkedIn" button will initiate authorization, but the 'auth' callback will never fire. Instead, you'll get a CORS error in the console:
"Uncaught SecurityError: Blocked a frame with origin "https://platform.linkedin.com" from accessing a frame with origin ..."
All other environments seem to work fine (e.g. Chrome, FF, IE, Desktop Safari, Android browsers, etc.). I'm also able to reproduce the issue if I set the user agent to an iOS device in Chrome's dev tools, which makes me think the JS SDK is doing user-agent sniffing.
Is there a workaround? Is the LinkedIn dev team aware of this issue? Did I miss a Monday detail?
PS This is probably related: Sign in with Linkedin doesn't trigger callback on iOS Safari when using the JS API
According to LinkedIn's Getting Started with the JavaScript SDK page, the LinkedIn JavaScript SDK doesn't support iOS 5+.
Note: The JavaScript SDK is not compatible with iOS 5+.
#degrassesagan I think you need to do the following:
function onLinkedInLoad() {
IN.Event.on(IN,"auth",getProfileData);
IN.Event.on(IN,"success",onSuccess);
IN.Event.on(IN,"error",onError);
}
There is also a side issue, I have discovered, in relation to the LinkedIn JS SDK. I am using mobile Safari 10.3.3, and although the login business logic executes correctly, the URL flow does not.
After a successful login, the page goes to a LinkedIn 'Page Not Found' page, rather than closing the current browser tab, to reveal the owner's page underneath?
I am not sure whether this is connected to the original question or not, but I would be grateful, if anyone could shine a light on this problem.
::UPDATE:: LINKS DO NOT EXIST ANYMORE!
Very strange indeed, this is definitely a bug! I did a test with app_id from another application and it worked.
See for yourself:
https://apps.megalopes.com/megabraziltv/test.php (app_id correct)
https://apps.megalopes.com/megabraziltv/test2.php (app_id from another application)
---/---
I found several people with the same question and all the answers are equal:
Site URL is not same as REQUEST_URI (Redirecting URL)
My app setting are:
Secure Page Tab URL: apps.megalopes.com/megabraziltv/...
App Domain: megalopes.com
code:
<div id="fb-root"></div>
<script src="http://connect.facebook.net/pt_BR/all.js">
</script>
<script>
FB.init({
appId:'123456789', cookie:true,
status:true, xfbml:true
});
FB.ui({ method: 'apprequests',
message: 'Here is a new Requests dialog...'});
</script>
This simple code is not redirecting to any other url. I tested on the js console getting the same results. Sometimes works and sometimes I get this error message:
API Error Code: 191 API Error Description: The specified URL is not
owned by the application Error Message: redirect_uri is not owned by
the application.
Regardless of being page tab or canvas, you must identify the website Site URL in https://developers.facebook.com/apps
How I fixed:
App Domain: megalopes.com (domain)
Site URL: / Secure Canvas URL: / Secure Page Tab URL: https://www.megalopes.com (subdomain)
I think I have run into something similar before.
In the summary page of your app ensure both the Secure Canvas URL and Page Tab URL are populated.
The URL in my redirect_uri should have "http://" in the beginning. It was missing the protocol information, thus leading Facebook not to recognize my website and throw this annoying 191 error. I finally found out after one hour pulling the hair I (still) have left.
You have to create a channel page, which allows "cross domain communication in certain browsers"
This is an html page (saying /channel.html) on your server, which only contains :
<script src="//connect.facebook.net/en_US/all.js"></script>
And make the Javascript SDK aware of it :
FB.init({
appId: 'xxxxxx',
cookie: true,
channelUrl: location.protocol + '//' + location.host + '/channel.html'
});
More about this :
https://developers.facebook.com/docs/reference/javascript/FB.init/
https://developers.facebook.com/docs/reference/javascript/
It's because of domain URL that you mentioned in facebook's mistake. Domain URL wont be like www.site.com
Update your domain url like subdomain.site.com.
Now it surely work.