tarlepp / angular-sailsjs-boilerplate

'Boilerplate' for AngularJS + Sails.js
MIT License
307 stars 87 forks source link

Facebook authentication #98

Open Hanifb opened 8 years ago

Hanifb commented 8 years ago

I can see that facebook integration is a todo item, so i decided to give you a hand and start building on a Facebook authentication. So

The separation between front and backend makes the Passport strategy pretty worthless because it cant access the session on the front end.

So the front end must do the heavy lifting (maybe use an existing angular-module) and authenticate with facebook, then it must pass some form of data to Sails so sails can connect the model with the Facebook user.

Or am i missing something?

tarlepp commented 8 years ago

Hmm, basically this should work if you set the callback url from facebook to use backend url, and then in there create user + JWT.

Although I might be wrong with this, I hope that you make PR when you got this working.

markmssd commented 8 years ago

Any progress on Facebook integration? I'd like to give a hand if possible

Hanifb commented 8 years ago

Im currently busy on some other stuff, so it is on hold for me right now. Would gladly lend a hand if you get it started.

torsdag 15 oktober 2015 skrev markmssd notifications@github.com:

Any progress on Facebook integration? I'd like to give a hand if possible

— Reply to this email directly or view it on GitHub https://github.com/tarlepp/angular-sailsjs-boilerplate/issues/98#issuecomment-148383908 .

markmssd commented 8 years ago

Almost got it working, but ran into CORS problems... Looks like since the frontend and backend are on different domains, the Facebook callback gets rejected for some reason. XMLHttpRequest cannot load http://localhost:1337/auth/facebook. The request was redirected to 'https://www.facebook.com/v2.2/dialog/oauth?response_type=code&redirect_uri=…2Flocalhost%3A1337%2Fauth%2Ffacebook%2Fcallback&client_id=1503557523296237', which is disallowed for cross-origin requests that require preflight.

Hanifb commented 8 years ago

Have you whitelisted both domains in the Facebook-app settings?

torsdag 15 oktober 2015 skrev markmssd notifications@github.com:

Almost got it working, but ran into CORS problems... Looks like since the frontend and backend are on different domains, the Facebook callback gets rejected for some reason.

XMLHttpRequest cannot load http://localhost:1337/auth/facebook. The request was redirected to ' https://www.facebook.com/v2.2/dialog/oauth?response_type=code&redirect_uri=…2Flocalhost%3A1337%2Fauth%2Ffacebook%2Fcallback&client_id=1503557523296237', which is disallowed for cross-origin requests that require preflight.

— Reply to this email directly or view it on GitHub https://github.com/tarlepp/angular-sailsjs-boilerplate/issues/98#issuecomment-148400714 .

markmssd commented 8 years ago

I just tried that, setting it to 127.0.0.1 (I'm working locally), but the same problem persists...

Noteworthy: Only getting this problem when accessing from the frontend (http://localhost:3001/auth/facebook) If accessing directly from the backend (http://localhost:1337/auth/facebook), I get redirected to Facebook dialog where I have to authorize my app, and the callback is then triggered (http://localhost:1337/auth/facebook/callback?code=[very_long_string_here]#_=_)

"#=" is a string the Facebook appends to it, as per their doc, so the response is indeed returned from Facebook.

However, I then get a "Invalid User" since that user does not exist yet.

pierreburgy commented 8 years ago

This is how we implemented the providers authentification for Strapi : https://github.com/wistityhq/strapi-generate-users/blob/master/files/api/user/controllers/Auth.js

adnanrahic commented 8 years ago

Have you made any progress? I'm facing the same issue. Any help would be greatly appreciated.

Hanifb commented 8 years ago

So to make facebook auth to work with an Sails backend is pretty straightforward. First. Forget about facebook auth on the backend. Allt authentication will be handled on the front.

So the flow goes like this-> Frontend logs you in to facebook Frontend gets an auth key from facebook and passes the key to the backend The backend confirms the key with Facebook and recieves an fb_user_ID, finds the fb_user_ID registered in the user model logs it in and issues its own JWT to the frontend.

Voila, logged in.

Just remember, if you log out of facebook, you will still be logged in the frontend. Just must implement some kind of reauthorisation procedure with the backend and with facebook, and dont use to long lived tokens.

Hanifb commented 8 years ago

So this is what i use in the controller for checking facebook token and issuing JWT on the backend.

facecheck: function facecheck(req, res){
    fbgraph.setAccessToken(req.param("accessToken"));
    fbgraph.get("/me", function(err, result){
        if(err) return res.negotiate(err);

        if(!result) return res.serverError();

        console.log(result);

        User.findOne({'facebook_id': result.id}).exec(function(err, user){
            if(err) return res.negotiate(err);

            if(user){
                   res.json(200, {
                       user: user,
                       token: sails.services['token'].issue(_.isObject(user.id) ? JSON.stringify(user.id) : user.id)
                   });
               }

            return res.json(401, {
                message: "User not found"
            })
           })
    })
},