Let’s now implement login!
It’s going to be very similar to the registration, except we call /api/auth/login
, and we don’t have to handle the password confirmation. And contrary to registration, we fail if the user is not there yet.
Here is the endpoint we add in the server.js
file:
server.post('/api/auth/login', async (req, res) => {
passport.authenticate('local', (err, user, info) => {
if (err) {
res.statusCode = 500
res.end(
JSON.stringify({
status: 'error',
message: err
})
)
return
}
if (!user) {
res.statusCode = 500
res.end(
JSON.stringify({
status: 'error',
message: 'No user matching credentials'
})
)
return
}
req.login(user, err => {
if (err) {
res.statusCode = 500
res.end(
JSON.stringify({
status: 'error',
message: err
})
)
return
}
return res.end(
JSON.stringify({
status: 'success',
message: 'Logged in'
})
)
})
})(req, res, next)
})
As you can see, we also call the req.login()
method to log in the user, and we send the successful response back (or an error if something wrong happens).
We call this from the components/LoginModal.js
component.
Right now we have this content in that file:
components/LoginModal.js
export default props => (
<>
<h2>Log in</h2>
<div>
<form
onSubmit={event => {
alert('Log in!')
event.preventDefault()
}}>
<input id='email' type='email' placeholder='Email address' />
<input id='password' type='password' placeholder='Password' />
<button>Log in</button>
</form>
<p>
Don't have an account yet?{' '}
<a href='#' onClick={() => props.showSignup()}>
Sign up
</a>
</p>
</div>
</>
)
I’m going to copy most the content of the components/RegistrationModal.js
file in here, except we don’t have a password confirmation, and we do a POST request to /api/auth/login
:
import { useState } from 'react'
import axios from 'axios'
import { useStoreActions } from 'easy-peasy'
export default props => {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const setUser = useStoreActions(actions => actions.user.setUser)
const setHideModal = useStoreActions(actions => actions.modals.setHideModal)
return (
<>
<h2>Sign up</h2>
<div>
<form
onSubmit={async event => {
try {
const response = await axios.post('/api/auth/login', { email, password })
if (response.data.status === 'error') {
alert(response.data.message)
return
}
setUser(email)
setHideModal()
} catch (error) {
alert(error.response.data.message)
return
}
event.preventDefault()
}}>
<input
id='email'
type='email'
placeholder='Email address'
onChange={event => setEmail(event.target.value)}
/>
<input
id='password'
type='password'
placeholder='Password'
onChange={event => setPassword(event.target.value)}
/>
<button>Log in</button>
</form>
<p>
Don't have an account yet?{' '}
<a href='#' onClick={() => props.showSignup()}>
Sign up
</a>
</p>
</div>
</>
)
}
That’s it!
Try the application: you should be able to create a new user using the registration form, log out and then log in again. If you use the wrong password, it should give you an error.
The code for this module is available at https://github.com/flaviocopes/airbnb-clone-react-nextjs/commit/e71ec89a3b8a39c2197b38124b17d5afd321e652