Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular/Express/Passport - Authenticating with Google: No 'Access-Control-Allow-Origin

Context

I am building a stateless application using Angular, Express & PassportJS and want to authenticate users using their Google account. After authenticating a user, my goal is to use JWT tokens to be able to have a stateless application.

Angular 2 side

Upon clicking the Google sign in button, the following code gets executed in my service:

login() {
    return this.http.get('http://localhost:3000/api/auth/google');
}

Express side

On express, the following gets executed:

// This gets executed first after clicking the sign in using Google button.
router.get('/api/auth/google', passport.authenticate('google', {
    session: false,
    scope: ['profile', 'email']
}));

// Google sends me back here (callback).
passport.use(new GoogleStrategy({
        clientID: 'omitted',
        clientSecret: 'omitted',
        callbackURL: '/api/auth/google/callback'
    }, function (accessToken, refreshToken, profile, cb) {

        // Here, I obtain the profile and create a JWT token which I send back to the user.
        let jwtToken = generateToken(); // Code omitted for simplicity.

        cb(null, jwtToken); // assume success
    }
));

// After creating a JWT token, this will get executed. 
router.get('/api/auth/google/callback', (req, res, next) => {
    passport.authenticate('google', (err, jwtToken) => {
        res.status(201).json(jwtToken);
    })(req, res);
});

Error:

After clicking the 'sign in with Google' button (i.e. making the get request from Angular), I receive the following error:

Failed to load https://accounts.google.com/o/oauth2/v2/auth?response_type=code&redirect_uri=(long_string_here): No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

What I have tried

I have seen similar issues on Angular and React applications and while there are answers (which I have tried), there has been no 'accepted answer' that actually solves this issue. I'm truly appalled why this is such a problem:

The strange part is: if I directly call window.location.href = http://localhost:3000/api/auth/google instead of making a get request, it works fine. However, then the issue is that I am not able to obtain my JWT token as I am being redirected completely.

I have also tried to enabled CORS in many different ways in the backend and allowed all kinds of origins. This does not change anything.

An important note here is that my Angular application is running on port 4200 and my Express application on port 3000. However, even if I compile my Angular project and put it in the public folder of Express and serve it, I still get the same CORS issues!

like image 250
Moody Avatar asked Apr 17 '18 20:04

Moody


1 Answers

call like this from login,

flogin(){
 window.open('/auth/facebook',"mywindow","location=1,status=1,scrollbars=1, width=800,height=800");
let listener = window.addEventListener('message', (message) => {
  //message will contain facebook user and details
});

}

in server, i'm hoping you've passport facebook-stratagy working

  app.get('/auth/facebook', passport.authenticate('facebook', { scope: ['email'] }));


app.get('/auth/facebook/callback',
    passport.authenticate('facebook', { failureRedirect: '/auth/fail' }),
function(req, res) {
    var responseHTML = '<html><head><title>Main</title></head><body></body><script>res = %value%; window.opener.postMessage(res, "*");window.close();</script></html>'
    responseHTML = responseHTML.replace('%value%', JSON.stringify({
        user: req.user
    }));
    res.status(200).send(responseHTML);


});
like image 165
rohith Avatar answered Oct 19 '22 00:10

rohith