Comments (12)
@lynndylanhurley - I will put this on our list to work on once we ship what we're working on now. About 1-2 months. Gettin' married next week so time is a little tight!
from redux-auth.
Congrats 💯
from redux-auth.
@chriskozlowski - can you post the code for the request?
from redux-auth.
@lynndylanhurley Sure! I can't post the project as a repo but here are some excerpts. I could create a test repo if needed but that would take a little more time to set up. In case I wasn't totally clear above, the redux-auth fetch does work client side just fine. This issue only happened to me on the server. Made me wonder if the redux-auth fetch needs something that is only in the browser environment...
The component:
class ProjectsAppRoot extends Component {
static fetchData(store, props) {
return store.dispatch(fetchProjects());
}
...
The action creator:
import { fetch } from 'redux-auth';
// import fetch from 'isomorphic-fetch'; <-- This will work but doesn't send auth headers
export function fetchProjects() {
return (dispatch) => {
dispatch(requestProjects());
return fetch('http://127.0.0.1/api/v1/projects', { method: 'get' }) <-- This does not resolve
.then(response => response.json())
.then(json => dispatch(receiveProjects(json)));
};
}
The SSR middleware
store.dispatch(configure(
{
apiUrl: 'http://127.0.0.1',
tokenValidationPath: '/auth/validate_token',
authProviderPaths: {
google: '/auth/google_oauth2',
},
},
{
isServer: global.__SERVER__,
cookies: request.headers.cookie,
currentLocation: url,
}
)).then(({ redirectPath, blank } = {}) => {
store.dispatch(match(url, (error, redirectLocation, routerState) => {
if (redirectLocation) {
response.redirect(redirectLocation.pathname + redirectLocation.search);
} else if (error) {
console.error('ROUTER ERROR:', pretty.render(error));
response.status(500);
hydrateOnClient();
} else {
const rootComponent = (
<div>
<Provider store={store}>
<div>
<AuthGlobals />
<ReduxRouter />
</div>
</Provider>
</div>
);
const fetchingComponents = routerState.components
// if you use react-redux, your components will be wrapped, unwrap them
.map(component => component.WrappedComponent ? component.WrappedComponent : component)
// now grab the fetchData functions from all (unwrapped) components that have it
.filter(component => component.fetchData);
// Call the fetchData functions and collect the promises they return
const fetchPromises = fetchingComponents.map(component => {
let promise = component.fetchData(store, routerState) // <-- We don't make it past here bc the promise hangs
return promise;
});
Promise.all(fetchPromises)
.then(() => {
const status = getStatusFromRoutes(routerState.routes);
if (status) {
response.status(status);
}
response.send('<!doctype html>\n' +
renderToString(
<Html store={ store } component={ rootComponent } assets={ global.webpackIsomorphicTools.assets() } />
)
);
});
}
}));
});
from redux-auth.
What is the result of dispatch(receiveProjects(json))
? Are you sure that it returns something resolvable? For example, should you be doing something like this instead?
return fetch('http://127.0.0.1/api/v1/projects', { method: 'get' }) <-- This does not resolve
.then(response => response.json())
.then(json => Promise.resolve(dispatch(receiveProjects(json))));
from redux-auth.
Thanks for your help on this!
receiveProjects()
is just a plain object action creator that signals the api call succeeded and the response data can be merged into the redux state:
export function receiveProject(payload) {
return { type: RECEIVE_PROJECT, payload };
}
Actually, while working this out, I actually commented out those additional promise then
statements so it was isolating just the fetch call and the result was the same:
return fetch('http://127.0.0.1/api/v1/projects', { method: 'get' }) <-- This does not resolve
//.then(response => response.json())
//.then(json => dispatch(receiveProjects(json)));
The hope was to just get the request to happen. It definitely isn't firing off as nothing even shows in the rails log. Of course the response data would not ultimately be merged into the state so I wouldn't see it in the rendered html but I was just hoping to get it to render and then add those additional promise then
statements back in.
Take a look at this code from utils/session-storage.js
. This file has the retrieveData
function that looks like it tries to load the auth info from localStorage or a cookie depending on whats available. This function is used by the redux-auth fetch function to generate the auth headers:
// even though this code shouldn't be used server-side, node will throw
// errors if "window" is used
var root = Function("return this")() || (42, eval)("this");
... and then later ...
export function retrieveData (key) {
var val = null;
switch (root.authState.currentSettings.storage) {
case "localStorage":
val = root.localStorage && root.localStorage.getItem(key);
break;
default:
val = Cookies.get(key);
break;
}
// if value is a simple string, the parser will fail. in that case, simply
// unescape the quotes and return the string.
try {
// return parsed json response
return JSON.parse(val);
} catch (err) {
// unescape quotes
return unescapeQuotes(val);
}
Seems like this might not work in the server side use case?
I tried your suggestion just to be sure...no luck.
from redux-auth.
Actually now that I think about it, the bundled fetch
was meant to be used in the client, normally in the componentDidMount
phase of the component lifecycle. Is there a reason that the request needs to be made server-side in your app?
See these posts for more details:
- http://stackoverflow.com/questions/27139366/why-do-the-react-docs-recommend-doing-ajax-in-componentdidmount-not-componentwi
- https://facebook.github.io/react/tips/initial-ajax.html
from redux-auth.
Totally makes sense where you're coming from there. Here is the story on that:
We are building a public website and a private internal app that both use the same rails api (CORS). My goal is to get them both to authenticate with the rails api with different user classes and permissions which is why your libraries are a great fit. Both the public website and internal app are redux/react based. I have been posting about the internal app which I suppose doesn't absolutely need to SSR the page with data preloaded (although I'd prefer it). However, I will definitely need it for the public site so I render out the full content for SEO reasons.
I wonder if others would want to be able to hit an external api server side like this too? I would be willing to help improve the fetch wrapper to support this type of usage.
from redux-auth.
I implemented server-side fetch in my fork: https://github.com/yury-dymov/redux-oauth
Implementation details:
- I added new server action to update headers in redux without touching user;
- In fetch in getAuthHeaders and updateAuthCredentials I am checking if it server-side and updating session-storage.js instead of cookies/local storage and dispatching new action
from redux-auth.
@yury-dymov - do you want to merge that stuff into this repo?
from redux-auth.
@lynndylanhurley in my fork I dropped multiple endpoint support and it might take too much time from my side to merge my changes and test if I haven't forgot something to support correctly all your features, which I am not using.
But I will be more than happy if other folks, who want to have that functionality in their projects will provide PR based on my code.
from redux-auth.
I wonder if others would want to be able to hit an external api server side like this too? I would be willing to help improve the fetch wrapper to support this type of usage.
@chriskozlowski - I'll accept a PR for this if you have time.
from redux-auth.
Related Issues (20)
- Session expiry notifications
- Attempts to use browser-cookies when running on server
- Specifying API port 80 might cause auth calls to fail with 401
- Missing documentation
- Support for the new react-router 4 HOT 4
- Can we get rid of react-router? HOT 2
- Typo in Readme inducing error on signout
- Is this repo still supported/active? HOT 4
- Oauth Example
- Can i use this library for oath autentication with IdentityServer from asp net core?
- integration with nextjs HOT 1
- Unable to resolve module `react-redux` && Unable to resolve module `querystring` HOT 1
- Support for only client side?
- Is the project still maintained? HOT 10
- Security issue HOT 2
- Provide options to change what happens after successfull sign in
- Error Coming from Default Module HOT 6
- Possible to split into actions+reducers / views packages? HOT 3
- Successful integration with react-boilerplace? HOT 1
- Archive this project HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from redux-auth.