SSR and store changes
tanis2000 opened this issue · 4 comments
I'm experiencing an issue with SSR that's driving me mad. I've added authentication to this app and I'm storing a cookie with the auth token (JWT). The token is being passed down the pipe to the Go server so that I can actually send it to the JSVM when performing server side rendering.
This is working fine as the value of the cookie is available in the VM and I can read and log it to the console to check that it's actually there.
I then changed the toString.js
to dispatch my loginSuccess
action creator when the token is available.
My toString
is the following:
import React from 'react';
import { Provider } from 'react-redux';
import { renderToString } from 'react-dom/server';
import { match, RouterContext } from 'react-router';
import Helmet from 'react-helmet';
import cookie from 'react-cookie';
import createRoutes from './routes';
import { createStore, setAsCurrentStore } from '../store';
/**
* Handle HTTP request at Golang server
*
* @param {Object} options request options
* @param {Function} cbk response callback
*/
export default function (options, cbk) {
cbk = global[cbk];
let result = {
uuid: options.uuid,
app: null,
title: null,
meta: null,
initial: null,
error: null,
redirect: null,
token: options.token,
};
const store = createStore();
setAsCurrentStore(store);
try {
match({ routes: createRoutes({store, first: { time: false }}), location: options.url }, (error, redirectLocation, renderProps) => {
try {
if (error) {
result.error = error;
} else if (redirectLocation) {
result.redirect = redirectLocation.pathname + redirectLocation.search;
} else {
console.log('token');
let token = options.token;
console.log(options.token);
if (token !== null) {
store.dispatch(loginUserSuccess(token));
}
result.app = renderToString(
<Provider store={store}>
<RouterContext {...renderProps} />
</Provider>
);
const { title, meta } = Helmet.rewind();
result.title = title.toString();
result.meta = meta.toString();
result.initial = JSON.stringify(store.getState());
}
} catch (e) {
result.error = e;
}
return cbk(result);
});
} catch (e) {
result.error = e;
return cbk(result);
}
}
The problem is that the store.dispatch(loginUserSuccess(token));
line is breaking something even though there's no error or warning anywhere.
Basically if I try to access directly http://localhost:5001/usage
the response of the /api/v1/system/conf call is completely missing. If I remove that line it works again but then all my authentication flow is being ignored just like I was an anonymous user.
What am I doing wrong?
Could you paste loginUserSuccess
function here?
export function loginUserSuccess(token) {
cookie.save('token', token);
return {
type: LOGIN_USER_SUCCESS,
payload: {
token: token,
}
};
}
Actually I kind of solved this issue by moving that code to the onEnter
function on the main App component:
static onEnter({store, nextState, replaceState, callback}) {
let token = cookie.load('token');
if (token !== null && token !== '') {
store.dispatch(loginUserSuccess(token));
}
callback();
}
It looks like the real issue was the one I opened in gojax. The missing headers caused the server side fetch to fail at calling the authenticated functions as the bearer token was completely missing just like all the other headers. I'm going to submit a PR for gojax and eventually this should solve as well. I'll keep you posted.
olebedev/gojax#1 is closed. Is this still an issue? Seems like good info to keep around, nonetheless.