I have added require('./logout').default, to routes/index.js and created routes/logout/index.js like so:
export default {
path: '/logout',
action({ req, res }) {
req.session.destroy(function (err) {
res.redirect('/');
});
},
};
But the req and res params are undefined. Is this a correct way to implement a logout route?
I would also prefer to use a post request for logout, can I send a post request to this route?
These routes are used for isomorphic html rendering and executed on both server-side and client-side (in the browser).
Api routes like PUT, POST, etc. should exist on the server side only. For example you may find authentication api endpoints here: src/server.js
/* src/server.js#L75 */
app.post('/logout', (req, res) => {
req.session.destroy();
res.redirect('/');
});
I understand this, the reason I put it in routes/index.js was because I thought it could be done without refreshing the page.
But yeah, I guess there is nothing wrong with refreshing the page on logout. Thanks.
Any idea why there is no property session in req? ~Cannot read property 'destroy' of undefined (req.user exists and everything else seems ok)
You can override default behavior like this:
function logout(event) {
event.preventDefault(); // prevent page transition
fetch('/logout', { method: 'POST' }).then(() =>
window.location.reload() // stay at the same url
)
}
<Link to="/logout" onClick={logout}>Logout Link</Link>
<a href="/logout" onClick={logout}>Logout Anchor</a>
<button type="button" onClick={logout}>Logout Button</button>
<form action="/logout" method="post" onSubmit={logout}>
<button>Logout Form</button>
</form>
Also you can use redux action to logout user without page refresh:
const USER_LOGOUT = 'USER_LOGOUT'; // action type
function logout() { // redux action
return (dispatch) => {
dispatch({ type: USER_LOGOUT });
return fetch('/logout', { method: 'POST' })
.then(() => dispatch({ type: USER_LOGOUT, error: false }))
.catch(error => dispatch({ type: USER_LOGOUT, payload: error, error: true }))
}
}
const initialState = null;
function user(state = initialState, action) { // redux reducer
switch (action.type) {
case USER_LOGOUT:
return action.error === false ? initialState : state;
default:
return state;
}
}
There is not session auth in the master branch, so you can just clear cookie for logout:
/* src/server.js#L75 */
app.post('/logout', (req, res) => {
res.clearCookie('id_token');
res.redirect('/');
});
@frenzzy directly sending the POST request works great! (the first snippet you have posted)
However I have been trying to make the second snippet to work as well (on feature/redux branch) and I am not sure how to dispatch the logout action.
The action from your snippet returns a callback to which a dispatch function should be passed however I am a little lost on how to do this.
Consider we are in navigation.js and add
<Link className={s.link} to="#" onClick={user_logout}>Logout</Link>
What I tried, is adding following function
import { logout } from '../../actions/user';
function user_logout () {
var cb = logout();
cb(dispatch);
}
The thing is, I don't know where to get the dispatch function (or store, which has it). How should I go about doing this?
You may use mapDispatchToProps inside react-redux connect(): Redux - Usage with React
Or dispatch manually:
class LogoutButton extends React.Component {
static contextTypes = {
store: PropTypes.object.isRequired,
};
handleClick = () => {
this.context.store.dispatch(logout());
};
render() {
return <button type="button" onClick={this.handleClick}>Logout</button>;
}
}
Thanks! For anyone interested, this is what I did:
export default connect(state => ({ user: state.user }), dispatch => ({ logout_click: bindActionCreators(logout, dispatch) }))(withStyles(s)(NavLogin));
Also, I had to add credentials: 'same-origin' to the logout post like so:
return fetch('/logout', { method: 'POST', credentials: 'same-origin' })
Otherwise on page refresh it logged me back in on FE (I wasn't properly logged out)
Most helpful comment
You can override default behavior like this:
Also you can use redux action to logout user without page refresh:
There is not session auth in the master branch, so you can just clear cookie for logout: