最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - MEAN stack Facebook authorization error: No 'Access-Control-Allow-Origin' header? - Stack Overflow

programmeradmin5浏览0评论

I am trying to make facebook-authorization on my MEAN stack application. I am using passport and passport-facebook. I am not using jade or ejs, I want to use pure angularjs. When I run my application and click "sign in" button, I get the following error:

XMLHttpRequest cannot load ;redirect_uri=http%…2Flocalhost%3A3030%2Fauth%2Ffacebook%2Fcallback&client_id=....  
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3030' is therefore not allowed access.

I have made some research and found that node cors module may fix this, but it didn't.

What have I done wrong and how can I fix that?

Here is my routes.js file (server-side):

app.get('/auth/facebook', passport.authenticate('facebook'));

app.get('/auth/facebook/callback', passport.authenticate('facebook', {
    successRedirect: '/success',
    failureRedirect: '/error'
}));

app.post('/success', function(req, res, next) {
    User.findById(req.session.passport.user, function(err, user) {
        if(err){ 
            res.send({success:false}); 
        }else{ 
            res.send({success:true,user: user});
        }
    });
});

app.get('/logout', function(req, res){
    req.logout();
    res.redirect('/');
    res.end();
});

app.post('/error', function(req, res, next) {
    res.send({success:false});
});

Here is my passport.js file (server-side):
Note: clientID, clientSectret, and callbackURL is in another file (config.js). But they are valid.

passport.use(new FacebookStrategy({
    clientID: config.facebookAuth.clientID,
    clientSecret: config.facebookAuth.clientSecret,
    callbackURL: config.facebookAuth.callbackURL
    },
    function(accessToken, refreshToken, profile, done) {
        User.findOne({ oauthID: profile.id }, function(err, user) {
            if(err) { console.log(err); }
            if (!err && user != null) {
                done(null, user);
            } else {
                var user = new User({
                    oauthID: profile.id,
                    name: profile.displayName,
                    created: Date.now()
                });
                user.save(function(err) {

                    if(err) {
                        console.log(err);
                    } else {
                        console.log("saving user ...");
                        done(null, user);
                    }
                });
            }
        });
    }
));


// serialize and deserialize
passport.serializeUser(function(user, done) {
    console.log('serializeUser: ' + user._id)
    done(null, user._id);
});
passport.deserializeUser(function(id, done) {
    User.findById(id, function(err, user){
        console.log(user)
        if(!err) {done(null, user);}
        else {done(err, null)}
    });
});

And here is my express config file: express.js (server-side):

var express = require('express'),
    passport = require('passport'),
    cookieParser = require('cookie-parser'),
    bodyParser = require('body-parser'),
    session = require('express-session'),
    cors = require('cors');

var whitelist = [''];
var corsOptions = {
  origin: function(origin, callback){
    var originIsWhitelisted = whitelist.indexOf(origin) !== -1;
    callback(null, originIsWhitelisted);
  }
};

module.exports = function (app, config) {
    app.set('view engine', 'ejs');
    app.use(cookieParser());
    app.use(bodyParser());
    app.use(cors(corsOptions));
    app.use(session({secret:"car advisor secret"}));
    app.use(passport.initialize());
    app.use(passport.session());
    app.use(express.static(config.rootPath+"/public"));
}

CLIENT SIDE

Here is my html file:

<body>
    <div class="navbar-right" ng-controller="LoginCtrl">
        <form class="navbar-form" >
            <a class="btn btn-primary" ng-click="signin()" ng-show="!identity.isAuthenticated()">Sign in</a>
            <a class="btn btn-primary" ng-click="signout()" ng-show="identity.isAuthenticated()">Sign out | {{identity.currentUser.name}}</a>
        </form> 
    </div>
    <ng-view></ng-view>

Here is my login controller:

$scope.signin = function(username, password) {
    authService.authenticateUser(username, password).then(function(success) {
        if (success){
            console.log("You have successfully signed in!");
        }
    });
}

$scope.signout = function() {
    authService.logoutUser().then(function() {
        console.log("You have successfully signed out!");
        $location.path('/');
    });
}

And here is my service that handles server munications (authService.js):

carApp.factory('authService', function($http, Identity, $q, $cookieStore, $resource) {
return {
    authenticateUser: function(username, password) {
        var dfd = $q.defer();
        $http.get('/auth/facebook').
            success(function(data, status, headers, config) {
                if (data.success) {
                    Identity.currentUser = response.data.user;
                    $cookieStore.put('user', response.data.user);
                    dfd.resolve(true);
                } else {
                    $cookieStore.remove('user');
                    dfd.resolve(false);
                }
            });
        return dfd.promise;
    },
    logoutUser: function() {
        var dfd = $q.defer();
        $http.get('/logout').success(function() {
            Identity.currentUser = undefined;
            $cookieStore.remove('user');
            dfd.resolve();
        });
        return dfd.promise;
    }

I am trying to make facebook-authorization on my MEAN stack application. I am using passport and passport-facebook. I am not using jade or ejs, I want to use pure angularjs. When I run my application and click "sign in" button, I get the following error:

XMLHttpRequest cannot load https://www.facebook./dialog/oauth?response_type=code&redirect_uri=http%…2Flocalhost%3A3030%2Fauth%2Ffacebook%2Fcallback&client_id=....  
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3030' is therefore not allowed access.

I have made some research and found that node cors module may fix this, but it didn't.

What have I done wrong and how can I fix that?

Here is my routes.js file (server-side):

app.get('/auth/facebook', passport.authenticate('facebook'));

app.get('/auth/facebook/callback', passport.authenticate('facebook', {
    successRedirect: '/success',
    failureRedirect: '/error'
}));

app.post('/success', function(req, res, next) {
    User.findById(req.session.passport.user, function(err, user) {
        if(err){ 
            res.send({success:false}); 
        }else{ 
            res.send({success:true,user: user});
        }
    });
});

app.get('/logout', function(req, res){
    req.logout();
    res.redirect('/');
    res.end();
});

app.post('/error', function(req, res, next) {
    res.send({success:false});
});

Here is my passport.js file (server-side):
Note: clientID, clientSectret, and callbackURL is in another file (config.js). But they are valid.

passport.use(new FacebookStrategy({
    clientID: config.facebookAuth.clientID,
    clientSecret: config.facebookAuth.clientSecret,
    callbackURL: config.facebookAuth.callbackURL
    },
    function(accessToken, refreshToken, profile, done) {
        User.findOne({ oauthID: profile.id }, function(err, user) {
            if(err) { console.log(err); }
            if (!err && user != null) {
                done(null, user);
            } else {
                var user = new User({
                    oauthID: profile.id,
                    name: profile.displayName,
                    created: Date.now()
                });
                user.save(function(err) {

                    if(err) {
                        console.log(err);
                    } else {
                        console.log("saving user ...");
                        done(null, user);
                    }
                });
            }
        });
    }
));


// serialize and deserialize
passport.serializeUser(function(user, done) {
    console.log('serializeUser: ' + user._id)
    done(null, user._id);
});
passport.deserializeUser(function(id, done) {
    User.findById(id, function(err, user){
        console.log(user)
        if(!err) {done(null, user);}
        else {done(err, null)}
    });
});

And here is my express config file: express.js (server-side):

var express = require('express'),
    passport = require('passport'),
    cookieParser = require('cookie-parser'),
    bodyParser = require('body-parser'),
    session = require('express-session'),
    cors = require('cors');

var whitelist = ['https://www.facebook.'];
var corsOptions = {
  origin: function(origin, callback){
    var originIsWhitelisted = whitelist.indexOf(origin) !== -1;
    callback(null, originIsWhitelisted);
  }
};

module.exports = function (app, config) {
    app.set('view engine', 'ejs');
    app.use(cookieParser());
    app.use(bodyParser());
    app.use(cors(corsOptions));
    app.use(session({secret:"car advisor secret"}));
    app.use(passport.initialize());
    app.use(passport.session());
    app.use(express.static(config.rootPath+"/public"));
}

CLIENT SIDE

Here is my html file:

<body>
    <div class="navbar-right" ng-controller="LoginCtrl">
        <form class="navbar-form" >
            <a class="btn btn-primary" ng-click="signin()" ng-show="!identity.isAuthenticated()">Sign in</a>
            <a class="btn btn-primary" ng-click="signout()" ng-show="identity.isAuthenticated()">Sign out | {{identity.currentUser.name}}</a>
        </form> 
    </div>
    <ng-view></ng-view>

Here is my login controller:

$scope.signin = function(username, password) {
    authService.authenticateUser(username, password).then(function(success) {
        if (success){
            console.log("You have successfully signed in!");
        }
    });
}

$scope.signout = function() {
    authService.logoutUser().then(function() {
        console.log("You have successfully signed out!");
        $location.path('/');
    });
}

And here is my service that handles server munications (authService.js):

carApp.factory('authService', function($http, Identity, $q, $cookieStore, $resource) {
return {
    authenticateUser: function(username, password) {
        var dfd = $q.defer();
        $http.get('/auth/facebook').
            success(function(data, status, headers, config) {
                if (data.success) {
                    Identity.currentUser = response.data.user;
                    $cookieStore.put('user', response.data.user);
                    dfd.resolve(true);
                } else {
                    $cookieStore.remove('user');
                    dfd.resolve(false);
                }
            });
        return dfd.promise;
    },
    logoutUser: function() {
        var dfd = $q.defer();
        $http.get('/logout').success(function() {
            Identity.currentUser = undefined;
            $cookieStore.remove('user');
            dfd.resolve();
        });
        return dfd.promise;
    }
Share Improve this question edited Oct 29, 2014 at 17:33 Michael asked Oct 29, 2014 at 17:27 MichaelMichael 16.2k39 gold badges98 silver badges145 bronze badges 1
  • I am facing similar issue..did you got the solution for this..? can you help me with that – Shashank Singh Commented Dec 23, 2016 at 15:10
Add a ment  | 

3 Answers 3

Reset to default 4

I'm not sure if this solves your problem but i recently went through something similar trying to make a facebook log in for an angular app. make sure in your facebook app setting page,

https://developers.facebook./apps/{your_app_id}/settings/   

change the "Site URL" to whatever your local host is.for example:

http://localhost:8080/

hello I'm not sure if this help you try

    app.config(['$httpProvider', function ($httpProvider){
      $httpProvider.defaults.useXDomain = true;
   // $httpProvider.defaults.cache = true;
      $httpProvider.defaults.withCredentials = true;
   // $httpProvider.defaults.xsrfCookieName = '';
   // $httpProvider.defaults.xsrfHeaderName = '';
      delete $httpProvider.defaults.headers.mon['X-Requested-With'];
}]);

You can't make an ajax request to a different address. Even if the address is the same and the port is different, you'll have "same origin policy" problems.

You can do it using nginx and redirecting the request with proxy_pass.

Check: http://distinctplace./infrastructure/2013/10/14/internal-redirect-to-another-domain-with-proxy_pass-and-nginx/

something like

server
{
  listen 80; 
  server_name localhost;

  location /auth/facebook/request {
    proxy_pass http://(...)facebook./(...);
  }
}
发布评论

评论列表(0)

  1. 暂无评论