Reputation: 2863
I have two apps that are linked: one acting as the server (express) on port 5000, and the other as the client (React) on port 3000. I want to send data from the server to the client--to a specific page.
Flow:
localhost:3000
localhost:5000/api/callback
router.get('/api/callback')
fetches an authorization token based on the code and then redirects to localhost:3000/dashboard
(where a Dashboard component is shown via React Router)I realize that this is quite convoluted but that's basically where I'm having trouble; I don't fully get how to make Express and React communicate properly.
In server.js:
router.get('/callback', async (req, res) => {
const code = req.query.code;
const token = await getAuthorizationTokenFromExternalSite(code);
// Poor attempt to persist data
res.cookie('token', token);
// Poor attempt to let the user see this URL
res.redirect("http://localhost:3000/dashboard");
});
router.get('/dashboard', (req, res) => {
res.send({ token: req.cookies['token'] });
});
client/src/App.js
class App extends Component {
render() {
return(
<BrowserRouter>
<div>
<Route exact path="/" component={LoginPage} />
<Route path="/dashboard" component={Dashboard} />
</div>
</BrowserRouter>
);
}
}
export default App;
client/src/Dashboard.js
class Dashboard extends Component {
state = { token: null };
componentDidMount() {
fetch('/api/dashboard')
.then(res => this.setState({ token: res.token }));
}
render() {
return(
<div>
Tis the Dashboard, the token is {this.state.token}.
</div>
);
}
}
export default Dashboard;
What is the correct way to go about bringing the user back to localhost:3000
from the server, and then to pass on the necessary data?
Upvotes: 4
Views: 4757
Reputation: 3227
I think it is pretty common to put this token in a hash in the #<token here>
bit of the uri you redirect the user to the UI. The #
segment of a uri is not sent to the backend server you redirect to so is somewhat better than just putting it behind ?
. Then you can (in the ui) parse the token out and use it to make requests. Commonly by passing the http header Authorization: Bearer ${token}
.
Putting it in a cookie can be OK if its http-only (which means the UI can't programmatically access it), and the backend knows to look at the cookie to get the token. This is more complex long term (in my opinion) than just passing the access token to the UI via the URL.
Reviewing flow/dynamics of auth; in case it turns out to be helpful:
Option 2 can be easier if you have multiple providers to work with; e.g. facebook & google & dropbox, AND you have a server to manage the tokens. It is the more classic way of doing things.
Option 1 is serverless, just redirect back to your app and have the UI do whatever auth flow is necessary, managing the tokens and things in the UI code.
Upvotes: 5