0

So I'm having a problem getting my MEAN stack application to provide oauth with Facebook using PassportJS. Namely, I can't figure out how to get CORS to work on the Angular side of the application.

In my application the angular application sends a get request through a user facing click action:

<button (click)="onFacebookLogin()" class="loginBtn loginBtn-facebook"> 
    <span><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/14082/icon_facebook.png"/></span>| Login with Facebook
</button>

which eventually leads to this get request in my loginService:

facebookLoginUser(): Observable <User> {
  return this.http.get('users/auth/facebook')
}

This of course takes me to my route which uses passport.js:

// This part is in a 'users' module which is why you don't see 'users' prepend the route
router.get('/auth/facebook', passport.authenticate('facebook', {
    scope: ['email', 'photos']
}))

Now this piece of code returns an error from Facebook saying that 'photos' is an improper scope (something that I will address later). My problem is that the request delivers no error to my server and instead delivers the error (and I would presume the eventual object) to the angular application (I see the error in the browser console). The browser, naturally, complains about this since facebook is trying to communicate with it on a request that it didn't initiate (cors). My question is, how do I fix this?

Recommendations from this SO question say that I must navigate to the suggest that I need to navigate to the page that I'm making the request from. I've tried making the button a link with an anchor element and href but that doesn't work. Also that question uses angular.js and I don't think providing a new route with my router and creating a whole new view seems very prudent. Besides that, I still feel like Facebook would be returning the user to the angular application and not my express application like I intend. Does andybody know what I should do?

Update Error Code

Failed to load https://www.facebook.com/dialog/oauth?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauth%2Ffacebook%2Fcallback&scope=email%2Cphotos&client_id=2087173708182970: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.
Stephen Agwu
  • 1,013
  • 2
  • 15
  • 29
  • Very cumbersome description. What is the actual error you're seeing in the browser console? Why do you think that you need to configure something CORS-related in the angular app? CORS is actually negotiations between server and browser, it does not require you to somehow configure client app. – Alexander Leonov Apr 20 '18 at 15:41
  • sorry if I wasn't clear enough, and I've updated the question with the error provided by the browser. – Stephen Agwu Apr 20 '18 at 17:00
  • I'm thinking it is a question of cors because of the error provided to me and the fact that the other questions I looked up lead to believe it has something to do with cors. The other question I looked up says that my server responds to my angular app with a 302 redirect to facebook. I've confirmed this in the devtools network tab. I believe facebook responds to this redirect (to my angular app) rather than targeting my express app. I'm wondering what to do about this – Stephen Agwu Apr 20 '18 at 17:03
  • Well, if you believe that it is related to CORS then you need to provide all the browser-server communications related to this call. 302 can actually be prohibited code at some stages of CORS negotiations. – Alexander Leonov Apr 20 '18 at 18:13
  • it looks like it's targeting your Server (unless you have Angular app in port 3000). Try `ngrok` and set up your Facebook Callback URI to your Ngrok URL. Look up `ngrok` – Chau Tran Apr 20 '18 at 18:40
  • Well this is my bad. In the dev section of Facebook I entered what I thought to be an http uri. Meanwhile I didn’t know that Facebook automatically converts this to an https protocol (no matter what I do! Even if I have force https only unchecked!!). As I haven’t configured a ssl/tsl connection I can’t receive a callback. I’m not sure this is the end all be all problem, but I do know that this is the problem that I’m facing now. Sorry friends. – Stephen Agwu Apr 20 '18 at 22:15
  • It is not actually a CORS problem, but one of making this request in the wrong way to begin with. The user has to interact with the login dialog - and that of course can’t happen, if you tried to request it in the background. You need to _redirect_ the user to the login dialog URL in their browser - anything that tries to do anything AJAX-y in that regard is fundamentally wrong to begin with. – CBroe Apr 23 '18 at 07:12
  • Ok I get that. But what would be the correct way of making this redirect happen? – Stephen Agwu Apr 23 '18 at 12:34
  • finally figured it out – Stephen Agwu Apr 23 '18 at 13:28

1 Answers1

0

As CBroe commented, the method I was using to make the call was wrong as it couldn't be performed in an ahax-y way. I ended up using an anchor tag with an target=_blank attribute with an href that pointed directly at my backend passport facebook oauth route. So something like this:

<a href="http://localhost:3000/users/auth/facebook" target="_blank" class="loginBtn loginBtn-facebook">
    <span><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/14082/icon_facebook.png"/></span>| Login with Facebook
</a>

Everything works now

Stephen Agwu
  • 1,013
  • 2
  • 15
  • 29