Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

React router help

So I am trying to make a react app that will pull together everything I know with web development. My goal is to have a log in/ sign up where someone can log in and put what their subscriptions are (netflix, hbo) e.c.t. and it will spit out movies by category. from all of those streaming services in one place. I have been working on this for about a month and have most of it done. Almost everything I have learned has been through tree house. I am currently trying to make the ProtectedRoutes component that was built in the React Authentication course. But, I am trying to make it accept JWT tokens stored in an HTTP cookie. In the react course it pulled the data from the context api that was set up. I am trying to make it so that it is more secure. ideally I would like it to make a call to my api to authenticate the JWT before allowing them to the protected routes.

I cant seem to get it to work. I have tried multiple things but it seems everything I do it throws an error. I am open to suggestions for what ever works. I do not know redux but if I need to go that route then I do. I am open to anything just no client side cookies for the JWT, or local or session storage. From what I understand these are venerable to attacks. I have also heard of server side rendering React. Would this solve the issue? I feel like that defeats the purpose of react for the client side and express/ node for backend right?

I hope to hear from you guys soon! :)

here is the ProtectRoutes function I am referring to with notes

function PrivateRoute({ component: Component, ...rest }) {

    return (
        // wraps route in a context Consumer tag.
        <Consumer>
            {(context) => (
                // then passes context to the Route
                <Route
                    // rest of the props
                    {...rest}
                    // what Route will render
                    render={(props) =>
                        // if JWT is valid then render protected Component if not redirect to sign in page
                        (part that needs to be true if they have a valid jwt Token) ? (
                            <Component {...props} />
                        ) : (
                            <Redirect
                                to={{
                                    pathname: "/signin",
                                    state: { from: props.location },
                                }}
                            />
                        )
                    }
                />
            )}
        </Consumer>
    );
}
export default PrivateRoute;

Here is what the router looks

                <Router>
                    <Switch>
                        <Route exact path="/" component={Public} />
                        <PrivateRoute path="/movies" component={MoviesWithContext} />
                        <PrivateRoute path="/settings" component={SettingsWithContext} />
                        <Route path="/signIn" component={UserSignInWithContext} />
                        <Route path="/signup" component={UserSignUpWithContext} />
                        <Route path="/signOut" component={UserSignOutWithContext} />
                        <Route component={NotFound} />
                    </Switch>
                </Router>

Hey Reggie Williams https://github.com/Tomessy/Public-Webflix.

Currently is is broken because of the private route not working so just a heads up on that. Also please don't mind my excessive console.logging especially on the backend.

Please let me know if you have any questions!

Also Reggie Williams or anyone else if you see anything you would change please let me know. I know I am using a lot of Promises and no async await. I am hoping this project will land me a developer position so any productive criticism is more then welcome! Thank you for taking the time to look at it!

Reggie Williams
Reggie Williams
Treehouse Teacher

Thanks Paul Messmer ! Which errors are you currently getting? Were there problems with your credentialCheck function? You should be able to include a function like credentialCheck in the routes you'd like to protect from the API side. Are you having trouble accessing the authentication status inside of the private route?

So far I'm seeing an error coming from createUser because response is not defined when you try to use it in your userSignUp component

I am very sorry Reggie Williams I should have clarified more. The error is showing up when I try to access localhost:3000/movies which is a protected route without the JWT (should redirect to the signin page. )

I also forgot to mention I have not implemented the JWT tokens on the signup route yet only the signin. I was hoping to figure this out first before spreading the problem to more of my app haha. I think I started to then decided to figure it out on the signin/signout so that is why I have the new Promise without returning things. I am very sorry all of this project is very not polished so far. So if you have any questions please let me know!

The credentialCheck was commented out because I tried to make it middleware but I could not get it to work and it is not needed as I can just repeat code for the minimal viable product.

Guil Hernandez Do you know how I should be able to do this?

Reggie Williams
Reggie Williams
Treehouse Teacher

Paul Messmer is the error you're getting Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

Reggie Williams
Reggie Williams
Treehouse Teacher

Paul Messmer When changing your private route from
function PrivateRoute( isValid, {component: Component, ...rest }) { to function PrivateRoute({component: Component, ...rest }) { then the signing page is rendered

Reggie Williams sorry for the late reply, When I do that and make the function call to check on the JWT token even if it is an async function it will still render the page before getting the results back from the server. So it breaks the authentication and authorization.

Reggie Williams
Reggie Williams
Treehouse Teacher

Paul Messmer is there a reason you call verify token in both the app.js and in the private route using the function imported for context?

Reggie Williams I think at that point in time I was trying to pass the result of verify token as a prop to Private Route. I think what I am going to have to do to solve this problem is do away with the private route function and then in protected routes load a loading component as I check the token validation then if it is valid show the user the component and if not then redirect them.

The react router would just have routes not protected routes. This is not a dry way of doing it but I think it will be ok for these two routes.

1 Answer

Reggie Williams
STAFF
Reggie Williams
Treehouse Teacher

Hey Paul Messmer ! Is this project in a public repository?