462 words
2 minutes
Redirect client back to previous page after authentication

You can view these tutorials to set up Redux in order to do this example

Code#

After setting up redux in your application you want to create a callback action.

Actions#

export const setCallbackLink = callbackLink => ({ type: 'SET_CALLBACK_LINK', callbackLink });

createStore#

import { createStore as reduxCreateStore } from 'redux'; const reducer = (state, action) => { if (action.type === 'SET_CALLBACK_LINK') { return Object.assign({}, state, { callbackLink: action.callbackLink }); } return state; }; const initialState = { callbackLink: '/', }; const createStore = () => reduxCreateStore(reducer, initialState) export default createStore;

Login Component#

Our login component changes a little now. I have my component setup as a separate component that handles all the login task. If you have yours setup differently, all you need to do is wrap it around a Redux Connect and import your actions. When a user clicks on the button, we will store the current browser location into our redux store. I am using Gatsby in this example and pass the location as a props to my login button

import React, { Component } from 'react'; import { Login } from 'auth/Auth'; import { connect } from 'react-redux'; import { setCallbackLink } from '../actions'; const mapStateToProps = ({ callbackLink }) => ({ callbackLink }); const mapDispatchToProps = dispatch => ({ setCallbackLink: callbackLink => dispatch(setCallbackLink(callbackLink)), }); class LoginButton extends Component { constructor(props) { super(props); this.login = this.login.bind(this); } componentDidMount() { const { setCallbackLink: setLink, pathname } = this.props; setLink(pathname); } login() { Login(); const { setAuthentication } = this.props; setAuthentication(); } render() { return ( <button onClick={this.login}> Log In </button> ); } } export default connect(mapStateToProps, mapDispatchToProps)(LoginButton);

Callback#

Our callback method also uses a similar convention that the login button uses. We just need to wrap our component with a Redux Connect. After that we grab the stored location from our Redux store. In my application, the index page just serves as a login, due to that I redirect the user to the search page instead of back to the index page. You can forgo that if/else statement.

import React, { Component } from 'react'; import loading from 'assets/images/loading.svg'; import { navigate } from 'gatsby'; import { handleAuthentication } from 'auth/Auth'; import { connect } from 'react-redux'; import { setCallbackLink } from '../actions'; const mapStateToProps = ({ callbackLink }) => ({ callbackLink }); const mapDispatchToProps = dispatch => ({ setCallbackLink: callbackLink => dispatch(setCallbackLink(callbackLink)), }); class Callback extends Component { componentDidMount() { const { callbackLink } = this.props; handleAuthentication(); setTimeout(() => { if (callbackLink === '/') { navigate('/search'); } else { navigate(callbackLink); } }, 1500); } render() { return ( <div style={{ position: 'absolute', display: 'flex', justifyContent: 'center', height: '98vh', width: '98vw', top: 0, bottom: 0, left: 0, right: 0, backgroundColor: 'white', }} > <img src={loading} alt="loading" /> </div> ); } } export default connect(mapStateToProps, mapDispatchToProps)(Callback);
Redirect client back to previous page after authentication
https://edwardbeazer.com/posts/redirect-client-back-to-previous-page-after-authentication/
Author
Edward Beazer
Published at
2018-11-02