2

I've built a backend using Loopback with passport auth. It requires that I first visit http://localhost:3001/auth/github, which redirects to GitHub, which either displays a login page, or redirects back to my app on port 3001.

Now I'm building a ReactJS frontend on :3000. It's supposed to send AJAX calls to the backend appending the auth token as a query string parameter. I've added port forwarding to the client's package.json, so all AJAX calls are handled correctly.

What I can't figure is how to get the auth token (received as a cookie from http://localhost:3001/auth/github/callback) to the client side. While my AJAX calls are proxied correctly, when I navigate to /auth/github, I'm still on the React-generated page, and my :3001 endpoint isn't hit. If I go to :3001/auth/github, I'm not getting my auth_token cookie by my frontend code.

In other words, I have two problems: 1. How to navigate to my backend's auth page (http://localhost:3001/auth/github) from the frontend? 2. How to get the cookie obtained in #1 to my frontend so that it could be used in the subsequent queries?

As I'm building a demo, I only need a quick and dirty solution that Just Works, but I'm willing to consider other ideas like opening a popup window and/or an IFrame.

1

2 Answers 2

3

if you are using Passport then, you just need to read the strategy docs. I am assuming the authentication is done through Oauth

Example with express

Routes.js

api.route('/auth/github')
    .get(PassportCtrl.auth);

  api.route('/auth/github/callback')
    .get(PassportCtrl.authCallback, PassportCtrl.redirect);

PassportCtrl.js

import passport from 'passport';

const auth = passport.authenticate('github', {
  scope : ['profile', 'email']
});

const authCallback = passport.authenticate('github');

const redirect = (req, res) => {
    res.redirect('/whereveryouwant');
}

const getAuthUser = (req, res) => {
  res.json({
    user : req.user
  })
}

const logOut = (req, res) => {
  req.logOut();

  res.redirect('/');
}

export default {
  auth,
  authCallback,
  redirect,
  getAuthUser,
  logOut
}

passport init

// adding cookie feature
app.use(cookieSession({
  maxAge : 30 * 24 * 60 * 60 * 100,
  keys : [process.env.COOKIE_SECRET]
}));

// initializing passport
app.use(passport.initialize());
app.use(passport.session());

I forgot, you have to proxy

webpack.config.js

 devServer: {
    proxy: { // proxy URLs to backend development server
      '/auth/github': 'http://localhost:3001',
      '/api/**' : {
        'target' : 'http://localhost:3001'
      }
    },
    hot : true,
    contentBase: path.join(__dirname, "dist"),
    historyApiFallback : true,
    compress: true,
    port: 8080
  }

React

import React from 'react';
import {connect} from 'react-redux';
import {Link} from 'react-router-dom';


class Header extends React.Component {
  renderContent () {
    const {auth} = this.props;
    switch (auth) {
      case null : return;
      case false : return (
        <li><a href='/auth/google'>Login with google</a></li>
      )
      default: return ([
        <li key={'logout'}><a href='/api/logout'>Log out</a></li>
      ])
    }
  }
  render () {
    const {auth} = this.props;
    return (
      <nav>
        <div className='nav-wrapper'>
          <Link className="left brand-logo" to={auth ? '/whereveryouwant' : '/'}>
            Your page Name
          </Link>
          <ul className='right'>
            {this.renderContent()}
          </ul>
        </div>
      </nav>
    );
  }
}

const mapStateToProps = (state) => {
  return {
    auth : state.auth
  }
}

export default connect(mapStateToProps)(Header);
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, but I think I have stated clearly that the backend code is done, I just need to use it properly from the React side.
@ulu I forgot some configuration you have to implement, I hope this helps
Thanks for adding the proxy setting, but I've already marked the other answer as correct, sorry!
2

Some suggestion to work on it:

  1. How to navigate to my backend's auth page (http://localhost:3001/auth/github) from the frontend?

Use Proxy on your React client (inside package.json) Example:

 {
  "name": "client",
  "version": "0.1.0",
  "private": true,
  "proxy": {
    "/auth/github": {
      "target": "http://localhost:3001"
    },
    "/api/*": {
      "target": "http://localhost:3001"
    }
  },
  "dependencies": {
    "axios": "^0.16.2",
    "materialize-css": "^0.99.0",
    "react": "^16.0.0-alpha.13",
    "react-dom": "^16.0.0-alpha.13",
    "react-redux": "^5.0.5",
    "react-router-dom": "^4.1.1",
    "react-scripts": "1.0.10",
    "react-stripe-checkout": "^2.4.0",
    "redux": "^3.7.1",
    "redux-form": "^7.0.1",
    "redux-thunk": "^2.2.0"
  },
}

So that when you access the api from your front you can refer it directly using '/auth/github'

  1. How to get the cookie obtained in #1 to my frontend so that it could be used in the subsequent queries?

I'm not sure about Loopback backend, but when I used Express, you can set using passport.session() from passport to get the session cookie

hope this helps.

1 Comment

While my simple proxy setting didn't work, yours did. That's because a simple setting works for all requests that don't have an "Accept: text/html" header. If you add a complex setting with path matching, it works for all requests, so that you can browse pages served by your backend. Source: github.com/facebook/create-react-app/blob/master/packages/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.