Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to manage OAuth in Node-Express / Vue web app?

I'm a bit confused as to how to manage the OAuth flow in my application. I can make it work, but I'm unsure of the best practices, and would like to find some good articles/tutorials/documentation on that topic.

My app is structured as follows:

  • A Vue front-end that makes HTTP requests via axios to a back-end
  • A Node.js / Express back-end that uses Passport.js allowing local, Google and Facebook strategies

Passport is configured like this:

passport.use(
    new GoogleStrategy(
        {
            clientID: process.env.GOOGLE_CLIENT_ID,
            clientSecret: process.env.GOOGLE_CLIENT_SECRET,
            callbackURL: '/api/login/google/callback'
        },
        async (accesToken, refreshToken, profile, done) => {
            try {
                let user = await User.findOne({ googleId: profile.id });
                if (user) {
                    if (
                        user.email != profile.emails[0].value ||
                        user.pic != profile.photos[0].value
                    ) {
                        user.email = profile.emails[0].value;
                        user.pic = profile.photos[0].value;
                        user.save();
                    }
                    return done(null, user);
                } else {
                    user = await User.findOne({
                        email: profile.emails[0].value
                    });
                    if (user) done(new UserError('existing-user'));
                    const newUser = await new User({
                        googleId: profile.id,
                        email: profile.emails[0].value,
                        name: profile.displayName,
                        pic: profile.photos[0].value
                    }).save();
                    return done(null, newUser);
                }
            } catch (e) {
                return done(e);
            }
        }
    )
);

And these are the auth methods in my login component:

methods: {
        async login() {
            await authClient.login(this.credentials);
        },
        async googleLogin() {
            window.open('/api/login/google', 'loginPopup', 'menubar=on');
            // window.location.href = '/api/login/google';
        },
        async facebookLogin() {
            window.location.href = '/api/login/facebook';
        },
        async requestResetToken() {
            await userClient.requestResetToken({
                email: this.emailReset
            });
        }
    }

My confusion comes from the fact that in order to start the OAuth flow, I need to actually leave my Vue app by linking to /api/login/google, which redirects to the Google OAuth page. Once the OAuth is completed, I'm not redirected to my Vue app but to the Node back-end (via the callback setup in Passport config).

One way to make it work is to open that OAuth flow in a popup window, track through my Vue app the content of that window, and as soon as I get the user object I close the window and login the user in the front-end. But somehow that doesn't seem quite right.

Should I find a way to actually have that callback function redirect to my Vue app and get the Vue app to deal with it? Any good resource online with examples to understand that clearly?

Thanks for your help!

like image 964
eichan Avatar asked Sep 24 '20 14:09

eichan


People also ask

How do I connect to Vue with node?

json resides and configures the appropriate API paths. With this in place, all the calls start with /api will be redirected to http://localhost:3080 where the nodejs API running. Once this is configured, you can run the Vue app on port 8080 and nodejs API on 3080 still make them work together.


1 Answers

:) Hello,

For an one page web app you should use Authorization Code Flow and with Passport after an oauth attempt you should have a middleware that will redirect you in case of failure or success : Passport Documentation:

enter image description here

And a good exemple for me was this Traversy Media - backend app with oAuth

I don't think that passport is the problem, the flow of the token is in your case...

like image 200
Stefan Dobre Avatar answered Nov 15 '22 00:11

Stefan Dobre