node.js/everyauth: Maintaining session information with auth request - facebook

Ok, so I'm banging my head against the wall trying to figure this out! I'm trying to authenticate via Facebook.
I've got node (0.6.13) running express on an amazon ec2 server. I'm using everyauth for auth, and I have mongodb (mongodb native and connect-mongodb) for persistence. Here is how I instantiate mongo:
var MongoStore = require('connect-mongodb');
var mongo = require('mongodb');
var mongoServer = new mongo.Server('localhost', 27017, {auto_reconnect: true, native_parser: true})
var mongoStore = new MongoStore({
db: new mongo.Db('test', mongoServer, {})
, reapInterval: 3000
});
I'm trying to authenticate through facebook using everyauth. So let's assume my app is running on port 3000, at http://ec2ip:3000/. My facebook app settings have the Website being redirected back to http://ec2ip:3000/.
Express is setup like so:
app.get('/', function (req, res) {
if(!req.session.auth || !req.session.auth.loggedIn)
{
console.log("Not authorized!");
res.redirect('/auth/facebook/');
}
else
{
console.log("Authorized!");
res.sendfile(__dirname + '/www/index.html');
}
});
This was working locally, before I put it on the server. What will happen is that it will correctly authenticate with facebook, and redirect to my website, however req.session.auth will always be undefined, and it will redirect forever. Even though I know it's successfully authenticated, it's just not passing the right session information.
It has something to do with setting up the redirect requests properly so session information is maintained, but I don't understand how it's working under the hood.
Any advice/help would be greatly appreciated. These are the related questions/problems I'm having, but I don't know how to apply it in my case: https://github.com/bnoguchi/everyauth/issues/189 and Node.js & Express session problem

Check what is the value in "req.session". Then go get directly the value in object that you need.

Related

POST to Salesforce API using Google Tag Manager and JSforce not working?

I want to use Google Tag Manager to send data to our Salesforce org for certain events on our website (user signup, conversion etc). After some research, I realized JSforce would be the easiest way to achieve this. I created a new connected app in Salesforce, tried out the Salesforce API using Postman and successfully managed to create a new user account via the API. Then I moved on to try and achieve the same thing in Google Tag Manager. I read JSforce's docs and attempted to implement everything. But, after multiple hours of troubleshooting and Google searching, I can't seem to make it work.
Here is my current code, which is in a 'tag' in Google Tag Manager that triggers on all pages (just for testing):
https://jsforce.github.io/start/#web-browser
<script src="//cdnjs.cloudflare.com/ajax/libs/jsforce/1.9.1/jsforce.min.js"></script>
<script>
jsforce.browser.init({
clientId: '<MYCLIENTID>',
redirectUri: 'https://cuttersclub.com'
});
https://jsforce.github.io/document/#access-token
var jsforce = require('jsforce');
var conn = new jsforce.Connection({
instanceUrl : 'https://um5.salesforce.com',
accessToken : '<MYACCESSTOKEN>',
});
https://jsforce.github.io/document/#create
conn.sobject("Account").create({ Name : 'My Account #1' }, function(err, ret) {
if (err || !ret.success) { return console.error(err, ret); }
console.log("Created record id : " + ret.id);
});
</script>
I'm getting this error in the browser console:
Uncaught ReferenceError: require is not defined
EDIT: Removing var jsforce = require('jsforce'); solved this problem and accounts are being created in Salesforce. But, now I am getting the following error in the browser console:
Access to XMLHttpRequest at '<URL>' from origin '<CALLBACKURL>' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
As mentioned in the JSforce docs, I think it may be something to do with proxy servers: https://github.com/jsforce/jsforce-ajax-proxy
I don't know that much about salesforce, but "require" is something from node.js, not a function that is implemented in the browser.
If I understand the documentation correctly, then for a browser project it should be enough to call the jsforce script via a script tag. You should not need any way to "require" files after that, since the jsforce script already contains everything you need. So you should be fine if you just remove the offending lines (i.e. all references to "require('jsforce');").

Sending mail from Firebase webapp

var express = require('express');
var app = express();
var nodemailer=require('nodemailer');
var transporter = nodemailer.createTransport('smtps://username#gmail.com:password#smtp.gmail.com');
app.get('/sendMail', function(req,res){
var mailOptions={
to: 'receiver#gmail.com',
subject: 'Test Mail',
html: 'Testing the Mail'
}
transporter.sendMail(mailOptions,function(err,response){
if(err){
res.end('Mail not sent');
}
else{
res.end('Mail sent');
}
});
}).listen(9091);
console.log('This is running');
I am developing a firebase web app. I need to send an email via my web app. I saw some tutorials and found some code. Using the above code I am able to send emails. It runs in the port 9091. The message will be sent when the address bar has www.mywebsite.com/sendMail. But when I host this page to Firebase what changes to be done in this code, whether there must be a change in the port number?. Please help to implement this code in my web app.
Update 2019: Alternatively, you can use the new Trigger Email Firebase Extension (currently in beta).
As I mentioned on my comment, the problem is: your web app was built with NodeJS and you're trying to host it on a static host environment (Firebase Hosting). But Firebase also has Cloud Functions - a service that let's you run functions on a NodeJS environment. So you should deploy your app to that service instead.
It's really easy to Get Started with Cloud Functions. And since you have already set up Firebase hosting, you can simply go to that directory and set up Cloud Functions by using this command:
firebase init functions
A new folder named "functions" will be created and an index.js file will be automatically added to that folder. Now that's the file where you're going to write your functions (we're actually just gonna need 1 function triggered by HTTP to send the email).
So in order to create this function, you would no longer need Express. you can remove that and then change a bit your index.js file to add firebase-functions, so it would become:
//var express = require('express'); No longer needed
//var app = express(); No longer needed
var nodemailer=require('nodemailer');
const functions = require('firebase-functions');
var transporter = nodemailer.createTransport('smtps://username#gmail.com:password#smtp.gmail.com');
exports.sendMail = functions.https.onRequest((req, res) =>{
var mailOptions={
to: 'receiver#gmail.com',
subject: 'Test Mail',
html: 'Testing the Mail'
}
transporter.sendMail(mailOptions,function(err,response){
if(err){
res.end('Mail not sent');
}
else{
res.end('Mail sent');
}
});
});
Now when you want to send a message, you can use this url: https://us-central1-<project-id>.cloudfunctions.net/sendMail
Replace <project-id> with your Firebase Project ID.

IBM Bluemix AppID - how log off / log out?

When using IBM Bluemix App ID, does anyone know how to log out a user? The Node.js server SDK on GitHub sample application and README includes this reference:
const LOGOUT_URL = "/ibm/bluemix/appid/logout";
I have tried various permutations but I haven't been able to find out what URL to use to log out the user (both hostname and extension).
Can anyone help, please?
Many thanks.
According to a posting at https://www.ibm.com/developerworks/library/iot-trs-secure-iot-solutions3/index.html , 'There is no explicit "logout" method at time of writing of this article'.
Having done some digging, killing the session will provide logout functionality. This can be achieved in Node.js with the following:
app.get("/logout", function(req, res){
// Destroy the session
req.session.destroy();
//return the main html file
res.sendfile(__dirname + '/views/index.html');
});
To log out the user, you can use the WebAppStrategy on your logout endpoint like the following:
app.get("/logout", function(req, res, next) {
WebAppStrategy.logout(req);
// If you chose to store your refresh-token, don't forgot to clear it also in logout:
res.clearCookie("refreshToken");
res.redirect("/");
});
Look at the Node SDK readme on WebAppStrategy https://github.com/ibm-cloud-security/appid-serversdk-nodejs.

Meteor: Implement facebook package outside of accounts-facebook

I've got a Meteor application with a multi-phase sign-up process. The accounts are based on the accounts-password package. In the step prior to account creation, the user needs to provide some profile information.
I'd like the user to be able to launch a Facebook OAuth flow which pre-populates the profile fields with information pulled from Facebook.
This all needs to happen pre-account-creation. I want to implement this with the facebook package that backs accounts-facebook.
At the moment I've got the OAuth flow happening by calling Facebook.requestCredential, but I'm not sure how to get an OAuth access token from the credential token that comes back. I suspect I need to pass this to the server and make an API call to get back an access token.
Any pointers as to how this should work would be much appreciated.
Facebook.requestCredential(function (credentialTokenOrError) {
if (credentialTokenOrError && credentialTokenOrError instanceof Error) {
// Error...
console.log(credentialTokenOrError);
} else {
// Credential Token string
console.log(credentialTokenOrError);
// Now perhaps a Meteor.call to a server method that
// 1. Retrieves an access token
// 2. Hits the graph API to get profile information and returns it to the client
}
});
Thanks,
Chris
I was having the same trouble of converting a credentialToken to an accessToken, only with Github. I've written up a gist that has code that should work very similarly. Essentially, there are two steps:
Within your Facebook.requestCredential callback function, call OAuth._retrieveCredentialSecret(tokenOrError), the result of which is the credentialSecret. Then use Meteor.call, passing in tokenOrError and credentialSecret, to call the Meteor.method you'll set up in the next step.
code (on client):
Github.requestCredential({
loginStyle: 'popup',
requestPermissions: ['gist']
}, function(tokenOrError) {
if (tokenOrError && tokenOrError instanceof Error) {
// Throw a Meteor error
console.log('error getting the token');
return;
}
var credentialSecret = OAuth._retrieveCredentialSecret(tokenOrError);
Meteor.call('getGithubAccessToken', tokenOrError, credentialSecret, function(err, accessToken) {});
});
On the server, set up a Meteor.method that takes your credentialToken and credentialSecret and calls Facebook.retrieveCredential. This function returns a credentials object from the _pendingCredentials Mongo Collection before deleting it from the collection. The access token is credentials.serviceData.accessToken. The credentials object could potentially be persisted in the user object in the Meteor.users collection (as it is in the accounts packages) or sent back to the user.
code (on server):
Meteor.methods({
getGithubAccessToken: function(credentialToken, credentialSecret) {
var credentials = Github.retrieveCredential(credentialToken, credentialSecret);
console.log('accessToken:', credentials.serviceData.accessToken);
return credentials.serviceData.accessToken;
}
});
I'm unfamiliar with the specifics of Facebook's Graph API so after these steps, you're on your own. Good luck!

Thinktecture IdentityServer3 Facebook Login Button Issue

I am using "IdentityServer3 - IdentityManager - MembershipReboot" in my project for User Management, Authentication & Resources Authorization.
I started from below sample and have gone good for creating users, authenticating them via /connect/token api and authorizing resources.
https://github.com/thinktecture/Thinktecture.IdentityServer.v3.Samples/tree/master/source/MembershipReboot
A brief architecture for my solution is
MySql as database. Communication via MembershipReboot.EF to MembershipReboot.
The client project is developed using html + angularjs.
Resources APIs are developed using Nancy & hosted on Owin+Katana in a seperate project.
Authentication Services(IdSvr+IdMgr+MR) are hosted in a seperate project.
Now I want to create a simple button/link clicking on which leads me to facebook login. The functionality of this button should be same as defined in IDSvr default login page's(https://localhost:44333/core/login?signin=4f909a877cc465afd26d72f60ec08f51) "Facebook button".
I have tried googled internet a lot but none of cases are matching my scenario.
I even tried to replicate the request-response behaviour of default IdSvr facebook login but that does not work as cookies are not being saved on end client.
Also i tried to hit "https://localhost:44333/core/signin-facebook" and getting response as HTTP/1.1 500 Internal Server Error from server. So i think might be I am somewhere wrong in setting facebook options in IdSrv project.
So if someone can just provide me a single IdSvr API to connect or tell me how to config Id Svr so that mapping a url can redirect it to facebook login. Or can tell me that where I am wrong in setting facebook authentication options in IdSrv.
A short and simple answer for my question is that I was looking for url.
https://localhost:44333/connect/authorize?client_id=implicitclient&response_type=token&scope=read&redirect_uri=http://localhost:8088/login/auth&nonce=random_nonce&acr_values=idp%3AFacebook&response_mode=form_post
Read further if you want to get better idea about this url
After lots of Hit&Trial & Study efforts, I have got solution for this. Well I think root cause for this problem was that sudden new technical things(Owin, Katana, OAuth, IdentityServer, IdentityManagement, MembershipReboot, Owin Facebook) and a meager time to understand them all.
I would advice folks that whoever is in same situation as me then first get an idea about OAuth. I found below link as a short and good one.
http://tutorials.jenkov.com/oauth2/index.html
After this I learnt that in our scenario we are dealing with two applications and hence two authentication.
For connecting User to Facebook. We created an app on developers.facebook.com
For connecting User to IdentityServer. We created a client in Clients.cs file on AuthenticationServices project.
So now here is the final solution.
localhost:44333 where AuthenticationService is running
locahost:8088 where FrontEnd services are running which iscalling AuthenticationService .
1. Create client app in AuthenticationServices as below
new Client
{
ClientName = "Implicit Clients",
Enabled = true,
ClientId = "implicitclient",
ClientSecrets = new List<ClientSecret>{
new ClientSecret("secret".Sha256())
},
Flow = Flows.Implicit,
RequireConsent = true,
AllowRememberConsent = true,
RedirectUris = new List<string>
{
"http://localhost:8088/login/auth" //This should be redirect url you want to hit after your app(not facebook app) redirects.
},
ScopeRestrictions = new List<string>
{
Constants.StandardScopes.OpenId,
Constants.StandardScopes.Profile,
Constants.StandardScopes.Email,
"read",
"write",
},
//SubjectType = SubjectTypes.Global,
AccessTokenType = AccessTokenType.Jwt,
IdentityTokenLifetime = 360,
AccessTokenLifetime = 360,
},
2 Create Authorize URL as below
var client = new OAuth2Client(new Uri("https://localhost:44333/core/connect/authorize"));
var startUrl = client.CreateAuthorizeUrl(
clientId: "implicitclient",
responseType: "token",
scope: "read",
redirectUri: "http://localhost:8088/login/auth",
nonce: "random_nonce",
responseMode: "form_post",
acrValues: "idp:Facebook");
The facebook app after successful authorization will redirect default to http://localhost:44333/signin-facebook. So no need to do any changes there.
Finally on http://localhost:8088/login/auth you will get access_token(+ few other parameters) after successful authentication. Here onwards you can use this token to access resources from Resources server.