AWS Amplify solved the authentication for developers. Let’s use it.
Install package, core library and react specific.
npm install --save aws-amplify
npm install --save aws-amplify-react
Create a AWS Mobile Hub project with awsmobile-CLI
npm install -g awsmobile-cli
awsmobile configure # first time use of CLI, setup with AWS_ACCESS_KEY and AWS_SECRET_KEY
awsmobile init
awsmobile user-signin enable
awsmobile user-files enable
awsmobile push
This guide have detailed information of how to setup a AWS Mobile Hub and work with AWS Amplify.
With CLI, AWS service settings are generated at src/aws-exports.js
. Open src/App.js
, add these lines to configure.
import Amplify from 'aws-amplify';
import aws_exports from './aws-exports';
Amplify.configure(aws_exports);
Open src/pages/Login.jsx
, change content to:
import React, { Component } from 'react';
import { Authenticator } from 'aws-amplify-react';
export default class Login extends Component {
render() {
return <Authenticator />
}
}
Now npm start
. Login becomes real
Got ahead sign up and sign in. Create a test user.
Notice after sign in the page becomes empty. It is time to update greetings in <Navigator>
First add ‘sign out’ button, right after ‘Greetings’ text
src/components/Navigator.jsx
...
import { SignOut } from 'aws-amplify-react';
...
render() {
...
<Navbar.Text>Greetings</Navbar.Text>
<SignOut />
...
}
Now we have a sign out button, but it always shows regardless user signed in or not. We need a way to be aware of user state. This means two tasks:
The fist task is done by an Auth
method currentAuthenticatedUser
.
The second task we can leverage an Amplify utility, Hub
. Events are dispatched to Hub
for every sign in / out. We just needed to listen to the events.
constructor(props) {
super(props);
this.loadUser = this.loadUser.bind(this);
Hub.listen('auth', this, 'navigator'); // Add this component as listener of auth event.
this.state = { user: null }
}
componentDidMount() {
this.loadUser(); // The first check
}
loadUser() {
Auth.currentAuthenticatedUser()
.then(user => this.setState({ user: user }))
.catch(err => this.setState({ user: null }));
}
onHubCapsule(capsule) {
this.loadUser(); // Triggered every time user sign in / out
}
Do the same to src/components/Main.jsx
, and modify its render
method to pass current user to pages.
render() {
const { user } = this.state;
return (
<Container as="main" role="main">
<div className="starter-template">
<HashRouter>
<Switch>
<Route
exact
path="/"
render={(props) => <Home user={user} />}
/>
<Route
exact
path="/login"
render={(props) => <Login user={user} />}
/>
</Switch>
</HashRouter>
</div>
</Container>
)
}
Modify src/pages/Login.jsx
so it renders depend on user state.
import React, { Component } from 'react';
import { Lead } from 'bootstrap-4-react';
import { Authenticator } from 'aws-amplify-react';
export default class Login extends Component {
render() {
const { user } = this.props;
return (
<React.Fragment>
{ !user && <Authenticator /> }
{ user && <Lead>You are signed in as <BSpan font="italic">{user.username}</BSpan>.</Lead> }
</React.Fragment>
)
}
}
Similar to src/pages/Home.jsx
.
npm start