DEV Community

Cover image for AWS Amplify - Mixed Public & Private Application Routing
Andrew Shanks
Andrew Shanks

Posted on

AWS Amplify - Mixed Public & Private Application Routing

Hi. This is my first post! I wanted to begin with something simple yet informative that has helped me on my side projects with Amplify.

This post assumes basic knowledge of setting up an Amplify project and is based on a React UI implementation.

Creating authenticated react applications with @AWSAmplify is simple when you want to wrap the App using withAuthenticator(App).

This works well when you are creating a demo site but when you want to send this to production you usually would want a homepage and some public links to talk about your products etc. There are many results on google relating to this kind of question and many ways to go about it.

Mixing public and private routes is usually a bit more involved. You would start using AmplifyAuthenticator in a custom component and track the users logged in state rather than use withAuthenticator.

This GitHub example by Mat Warger is very informative, if your site needs it and worth learning how it works. https://github.com/mwarger/amplify-auth-examples

A Simple Solution

But wait! I want to use the free goodness of withAuthenticator, my site isn't that complicated. Here is where nested routing using react-router comes in.

Declare you main App component which contains the top level routing that contains a ProtectedApp component which could be for admin functions.

App.js

const App = () => {
    return (
        <Router>
            <Switch>
                <Route path="/" exact render={() => <Home/>}/>
                <Route path="/admin" render={() => <ProtectedApp />}/>
            </Switch>
        </Router>
    );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

The ProtectedApp contains the routes for the admin function and this is wrapped in withAuthenticator(ProtectedApp)

ProtectedApp.js

import Amplify from "aws-amplify";
import awsExports from "./aws-exports";
Amplify.configure(awsExports);

const ProtectedApp = () => {

    return (
        <div>
            <Header />
            <Switch>
                <Route path="/admin" exact render={() => <AdminPanel />}/>
                <Route path="/admin/create" exact render={() => <CreateUser />}/>
            </Switch>
        </div>
    );
}

export default withAuthenticator(ProtectedApp);
Enter fullscreen mode Exit fullscreen mode

Now you can have private application routes protected but still able to use withAuthenticator to handle the auth while having easily accessible public routes for advertising and as a home page.

Hopefully this will help others navigate auth with Amplify!

Top comments (3)

Collapse
 
haskhaw profile image
Hassan Khawaja • Edited

Working on the local machine, however when published to Amplify, any protected path gives an AccessDenied error, like the previous poster mentioned.
Found a workaround here: victorleungtw.medium.com/fix-aws-a...

Basically need to add a Rewrite Rule in the Amplify Console for the app. In the Rewrite Rules screen, click Edit and then click Open Text Editor. Paste the below code and save, then try the URL again:
[
{
"source": "</^[^.]+$|\.(?!(css|gif|ico|jpg|js|png|txt|svg|woff|ttf)$)([^.]+$)/>",
"target": "/index.html",
"status": "200",
"condition": null
}
]

Collapse
 
awshanks profile image
Andrew Shanks

Thankyou. This is needed if it is a browser router rather than a hash router I believe.

Collapse
 
ganizanisitara profile image
GanizaniSitara

So interestingly this works on local, but as soon as the app is published the redirect to Cognito stops working and just an AccessDenied is given when trying to access the protected page. More digging needed.