Implementing facebook login in a Chrome extension - javascript

I am trying to use Facebook's Javascript SDK to implement a login button in a Chrome extension's popup.html page.
However when I call the FB.login() function, I get the following error: Given URL is not allowed by the Application configuration. Now, since it's a Chrome extension, I am not sure if I can provide a URL or domain for it.
So, what should I do in such a case?

You need to manually build the login flow, as it is explained here:
https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/v2.2
I'm building a login button for a chrome extension too, and I followed those instructions. However, whenever I try to access, I get this:
"Success
"SECURITY WARNING. Please use the url above as you would your password and do not share It with anyone."
This should be the right way... but I can't make It work. Maybe you can.

I am also trying to add fb-login feature in my chrome extension. I am using python-socialauth as authentication app for facebook in django app, which is the backend.
The steps I followed is as given below :
First I opened a window with facebook login link :
window.open('https://www.facebook.com/dialog/oauth?client_id=&response_type=token&redirect_uri=,"Facebook login", "width=635,height=290,left=0,top=0")
From the success url, I retrieved the access token and saved in chrome-local-storage.
Then I sent the token to my django-facebook-login view. But it is hitting error:
'Nonetype' object has no attribute 'encode'.
My code is as below :
if isinstance(request.backend, BaseOAuth1):
if request.REQUEST.get('backend') == "facebook":
oauth_token_secret = settings.SOCIAL_AUTH_FACEBOOK_KEY
if request.REQUEST.get('backend') == "google-oauth2":
oauth_token_secret = settings.SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET
token = {
'oauth_token': request.REQUEST.get('access_token'),
'oauth_token_secret': oauth_token_secret,
}
elif isinstance(request.backend, BaseOAuth2):
token = request.REQUEST.get('access_token')
else:
raise HttpResponseBadRequest('Wrong backend type')
user = request.backend.do_auth(token, ajax=True)
# age = request.POST.get('age', '')
login(request, user)
The line where I am hitting error is :
user = request.backend.do_auth(token, ajax=True)

Related

salesforce lightning auth an org from another org using user agent OAuth flow and store access token

I have connected app created in org 2 with OAuth enabled.
I'm using OAuth2.0 User agent workflow in org1 where I have lightning app.
Upon clicking a button (named auth target org) in lightning component page,
window.open(endpturl,'_self');
var currLoc = window.location.href;
alert ('Curr Loc is: ' + currLoc); //prints the URL from where I clicked button (named auth target org). Expected this statement to be executed after step 7. Hence not able to capture the access token.
Redirects to salesforce authorization/login page.
enter user credential --> click allow access.
Redirects to as per connected app configured callback URL
https://business-momentum-162-dev-ed.cs2.my.salesforce.com/services/oauth2/success#access_token=abc&instance_url=https%3A%2F%2Fdream-innovation-4602-dev-ed.cs40.my.salesforce.com&id=https%3A%2F%2Ftest.salesforce.com%2Fid%2F00D540000009LzUEAU%2F00554000000zjC5AAI&issued_at=1531980498349&signature=abc&scope=id+api&token_type=Bearer
BUT i'm not able to capture the access token as step 4 executed before step 7. Hence not able to capture access token. Please do let me know if there is way to get/capture access token.
client side controller code (**using window object**):
({ AuthTargetOrg : function (component, event, helper) {
var endpturl = 'https://test.salesforce.com/services/oauth2/authorize?response_type=token&client_id=abc123&redirect_uri=https%3A%2F%2Fbusiness-momentum-162-dev-ed.lightning.force.com%2Fservices%2Foauth2%2Fsuccess';
window.open(endpturl,'_self');
var currLoc = window.location.href;
alert ('Curr Loc is: ' + currLoc); // prints home page URL from where I clicked "auth target org" button, rather this statement expected to execute after step 7.
)}
Regards,
PJS
I believe you need to use Apex to handle the redirect of the Oauth dance. I've been struggling with this one myself and the problem is that in a lightning component you can't makes API calls directly to salesforce endpoints, it will throw all kinds of errors. I did however find this code example:
https://balkishankachawa.wordpress.com/tag/oauth-with-lightning/
Basically the solution is to use Apex and Lightning Out. Use Apex to receive your redirect from the Salesforce auth which can in turn get the token and pass it back to your lightning component.

Google Sharing API Leads to 500 Error and "Sharing is Unavailable" Message

I am attempting to set up the sharing ability on a web application that I am making. I have followed the steps on Google's Drive Sharing Instruction Page to the best of my ability. However, when I click the button, I get the expected popup, but with the message "Sorry, sharing is unavailable at this time. Please try again later."
The code I have is slightly different, as the init function name is being used elsewhere. The code I have is:
function initializeGoogleApis() {
/*
self._shareClient = {
'showSettingsDialog': function() {
devConsole.warning(0, "The sharing ability has not yet been implemented.");
}
};*/
gapi.load('drive-share', function() {
self._shareClient = new gapi.drive.share.ShareClient();
self._shareClient.setOAuthToken(self.clientId);
self._shareClient.setItemIds(self.realtimeUtils.getParam("id"));
});
}
Note the commented section. I had this to insure that the 'share' button on my page is loaded properly and calling the function, which it is. As explained in the title, when I click the button, I get a 500 error in the console.
At the bottom of the Google page listed above, it says the following:
The user is signed in to Google --> I have done this
The user has installed your app --> I don't know about this. For all other functionality, I only have to visit the site, so I am not sure what the difference here is.
The URL of the page that launches the dialog must have the same origin as the Open URL registered for the app --> I think I have this done. I followed the link on the page (here) and verified ownership.
I am also testing on the actual host, not on localhost as it states this will not work.
All the same, I get the following error:
GET https://drive.google.com/sharing/share?id=xxxxx_xxxxxxxxxx8&foreā€¦
d=false&client=postMessage&embedOrigin=http://www.example.com 500 ()
_.k.$l # cb=gapi.loaded_0:651
_.k.S # cb=gapi.loaded_0:651
_.k.Ql # cb=gapi.loaded_0:794
ys.kc # cb=gapi.loaded_0:791
Ts.OV # cb=gapi.loaded_0:822
Zs # cb=gapi.loaded_0:814
FM # cb=gapi.loaded_0:818
Ts.Ph # cb=gapi.loaded_0:818
pt.Na # cb=gapi.loaded_0:829
onclick # ?id=xxxxx_xxxxxxxxxxxxxxxxxxx:97
Any help would be appreciated
It looks like you are passing in your clientID instead of your OAuth token.

Paypal integration to Flask application

I am slightly misunderstand Paypal flow event after reading https://developer.paypal.com/docs/api/. I'd like to integrate express checkout and credit card payments to my site. I am using Flask and paypalrestsdk without any Flask extensions.
Here is excerpts from my app:
#app.route('/', methods=['GET'])
def index():
# Page with but form, price/quantity/name values
# are stored in hidden fields, "Buy now" acts as submit
return render_template('index.html')
#app.route('/payment/paypal', methods=['POST'])
def payment_paypal():
# Here I am creating dict with required params
payment_template = {
'intent': 'sale',
'payer': {'payment_method': 'paypal'},
'redirect_urls': {
'return_url': url_for('payment_paypal_execute'),
'cancel_url': url_for('payment_paypal_error')
},
......
}
payment = paypalrestsdk.Payment(payment)
if payment.create():
print('Payment "{}" created successfully'.format(payment.id))
for link in payment.links:
if link.method == "REDIRECT":
redirect_url = str(link.href)
print('Redirect for approval: {}'.format(redirect_url))
return redirect(redirect_urls)
#app.route('/payment/paypal/execute', methods=['GET'])
def payment_paypal_execute():
payer_id = request.args.get('payerId')
payment_id = request.args.get('paymentId')
token = request.args.get('token')
pending_payment = PayPalPayment.query.filter_by(token=token).filter_by(state='created').first_or_404()
try:
payment = paypalrestsdk.Payment.find(pending_payment.payment_id)
except paypalrestsdk.exceptions.ResourceNotFound as ex:
print('Paypal resource not found: {}'.format(ex))
abort(404)
if payment.execute({"payer_id": payer_id}):
pending_payment.state = payment.state
pending_payment.updated_at = datetime.strptime(payment.update_time, "%Y-%m-%dT%H:%M:%SZ")
db.session.commit()
return render_template('payment/success.html', payment_id=payment.id, state=payment.state)
return render_template('payment/error.html', payment_error=payment.error, step='Finallizing payment')
It is works fine, after clicking on button payment created succesfully (with state created) user redirected to approval page. There he click "Confirm"... And I never returned to my application, event when I specifying return_url! I.e. application could never be informed that buyer approved payment and it should be updated in my own database and new license should be sent to that person.
Problems:
I cannot find way to define some callback using pyhtonrestsdk. How to do it?
Even if I adding callback (I tried embed Express Checkout using pure Javascript button code) with data-callback my application was not called. I suspect because remote server could not call http://127.0.0.1/payment/paypal/success
User could close window with PayPal confirmation immediately after click "Confirm" so I could not trust browser redirection it it performed somehow later.
Finally, I suspect that I do not understand PayPal workflow clear, but I could not find more information about it event on developers portal.
As usual, devil hides in details. My main issue was following: paypal does not redirects me to my application, but I found that it redirects me (after confirmation) to URL which looks like https://sandbox.paypal.com/ with query string contains desired parameters. I.e. redirect_urls works as expected, just redirects me to wrong host.
After that I remembered that url_for generate relative links. So just added keyword _external=True I've been redirected to my application with all required arguments and payment successfully confirmed and executed.
I.e. correct redirect_urls block will looks like:
'redirect_urls': {
'return_url': url_for('payment_paypal_execute', _external=True),
'cancel_url': url_for('payment_paypal_error', _external=True)
}
Finally I've got following workflow:
Opened / (index) which has button Pay with PayPal It is image button inside form. Beside this button form contains hidden fields with amount, product name and quantity (actually if is not good idea because we cannot trust to user, so I storing only product_license_type_id which stored in DB and contains all required information about product).
Once clicked it POST form to '/payment/paypal' (paypal_create) where create object Payment with filling all fields. If call payment.create finished successfully it also creates record in my own database with payment_id and state (these fields related to paypal workflow, of course actually I am storing couple of other fields related to my app).
Once payment created on PayPal side, application look into response for list payment.links. We want one with rel == 'approval_url' and method == 'REDIRECT' and return flask.redirect(found_link)
On PayPal site buyer should click 'Approve', review shipping address and after that he will be immediately redirected to redirect_urls.return_url with following parameters in query string: PayerID, paymentId, token.
Once redirected back you should get this parameters from query string (keep in mind - it is case-sensitive!), find payment using PayPal API (payment = paypalrestsdk.Payment.find(payment_id)) and finalize it (payment.execute({"payer_id": payer_id}):).
When finalized payment changes status to approved.
....
PROFIT!
UPD: You do not need to turn on "AutoRedirect" in you selling account preferences and this approach suitable for integrating one account into multiple sites.

Single Sign out in All application using Auth0

I have URL "http://mywebsite.com" like this. I am using Auth0 for login my web application.Once the user logged in my application i will logging the user to my wordpress site and other website using the same login(Single Single Sign On). Once the user logged out from my application I need to logged out from wordpress and other website Also(Single Sign OFF/OUT).
Is it possible?
please suggest better option
Haven't had any experience with doing this personally, but this is straight from the docs on Auth0:
"This will clear any single sign-on cookies set by Auth0 for that user. If you also want to log the user out of their identity provider, add a federated query string parameter to the logout URL:
https://appname.auth0.com/v2/logout?federated"
I have the same requirement at this point. I am also using Auth0.
From their documentation, I understand that calling the Auth0 logout endpoint will only clear the SSO cookie on Auth0 and It does not logout of all other applications. It is our responsibility to clear the Sessions for each application.
The same is explained using a Auth0 anjularjs sample here https://github.com/auth0/auth0-single-sign-out-sample
Hope this helps.
#udayr answer led me on the right path:
I'm actually using ASP.Net Owin, so I created an overload of the LogOff endpoint at the Auth0AccountController of all my Apps like this:
[HttpGet]
public ActionResult LogOff() {
return this.LogOff("");
}
Then I added an SLO (Single Log Of) view and put the following code on it:
<iframe id="app1" height="0" width="0" src="http://app1.localtest.me/Auth0Account/LogOff"></iframe>
<iframe id="app2" height="0" width="0" src="http://app2.localtest.me/Auth0Account/LogOff"></iframe>
<h2 id="message">Logging off, please wait...</h2>
<script>
var app1Ready = false;
var app2Ready = false;
$('iframe').load(function (e) {
switch ($(e.target).attr("id")) {
case "app1":
app1Ready = true;
break;
case "app2":
app2Ready = true;
break;
}
if (app1Ready && app2Ready) {
$("#message").html("You have been Logged Off successfully!");
}
});
</script>
Basically, we need to make a Get call to the new LogOff end point via the iframes, the oly drawback is that all the aplications needs to know all the others applications' Log Off URLs, and this needs to implemented on all of them.
To log out the user from multiple applications, you can always check auth0 session has expired or not for the user by using the checkSession() method periodically. If there is no active session for the user, you can log out the user from your application.
// check every 15 minutes if the SSO session is still active
setInterval(function() {
// if the token is not in local storage, there is nothing to check (that is, the user is already logged out)
if (!localStorage.getItem('userToken')) return;
auth0.checkSession(function (err, data) {
if (err) {
// if we get here, it means there is no session on Auth0,
// then remove the token and redirect to #login
localStorage.removeItem('userToken');
window.location.href = '#login';
}
});
}, 900000)
https://auth0.com/docs/sso/current/single-page-apps#single-log-out
https://auth0.com/docs/migrations/guides/legacy-lock-api-deprecation#session-management
To clear the server session, all you need to do to redirect the user to /v2/logout endpoint.
https://auth0.com/docs/logout/guides/logout-auth0
If the users are logging in using the external identity provider, you can force the user to logout from IDP by adding federated querystring parameter when calling /v2/logout endpoint
https://auth0.com/docs/logout/guides/logout-idps
In the case of SAML IDP, you must configure SAML Logout URI in the connection settings.
https://auth0.com/docs/logout/guides/logout-saml-idps

Content Service for Google Apps Script returning HTML instead of JSON

Trying out the Content Service API and the example is returning HTML when it should be returning JSON, what am I doing wrong?
https://developers.google.com/apps-script/guides/content
function doGet(request) {
var events = CalendarApp.getEvents(
new Date(Number(request.parameters.start) * 1000),
new Date(Number(request.parameters.end) * 1000));
var result = {
available: events.length == 0
};
return ContentService.createTextOutput(JSON.stringify(result))
.setMimeType(ContentService.MimeType.JSON);
}
GAS from another file trying to make the request:
function myFunction() {
var url = "published URL";
url+="?start=1325437200&end=1325439000";
var options = {
method:"get"
}
var response = UrlFetchApp.fetch(url,options).getContentText();
response = JSON.parse(response); //error, unexpected token <
}
Your usage of ContentService is correct, the code works exactly as is. Here is a link to my copy of your code published as a web app:
https://script.google.com/macros/s/AKfycbzx2L643LHw0oQAq1jBmKQh2ju_znGfmdj78dUypj36iF-s91w/exec
The problem you are running into is related to Authorization or Authentication, if the published script is not authorized, an HTML error message is returned.
To check if that is your issue, simply access the published URL directly in your browser. If you see JSON displayed, then Authorization is not the problem. If you see the "Authorization is required to perform that action" error message, open your published script and choose "doGet" from the Run menu, then follow the authorization prompts.
More likely, the problem is related to how your script is published. In order to access your published script from another script, it must be published with the "Who has access to the app" setting as "Anyone, Even anonymous". If you use any other value, Google returns an HTML login page instead of your JSON response, and you get the error you are seeing.
This happens because requests sent from Google Apps Script via URLFetchApp are not authenticated, they don't carry the credentials of the user running the code with them, and come in as anonymous requests.
If you don't allow "Anyone, even anonymous" in your publishing settings, Google redirects non-authenticated requests to the Google login page.

Categories