Skip to content

Authentication ctd app implementation

Katja Durrani edited this page Oct 29, 2017 · 1 revision

Authentication - Implementation in the app

Server-side:

The passport strategies are defined in the auth directory
Database is initialized and data saved in auth-data (Sqlite)
User model defined in auth-models directory
-- auth

  • authJWT.js
  • index.js -- auth-data -- data (this directory is in .gitignore, not committed to repo)
    • userdb.sqlite -- auth-models -- users
    • index.js . . . routes.js ()

auth and authJWT modules containing the auth strategies are applied in the routes.js file. The requireAuth middleware function is also defined here, and applied to the relevant paths.

Client-side:

There are three components in the auth directory( src/components/routes/auth) that implement the main functionality:: LoginBar, Profile and RequireAuth

RequireAuth is a higher-order-component that takes another component as an argument. All that component does is, it checks if the authenticated property of the global state is set to true, and only in that case displays the wrapped component. If authenticated if false, it redirects to the profile page which contains the Login button.

In the src/index.js file that contains the routing for the app, RequireAuth is wrapped around the components that require authentication: Admin and ItemEdit

The Profile component handles the login process once the user has been authenticated via Github. In the componentWillMount method, the loginUser method is dispatched which obtains the token from the server and stores in in localStorage. It also sets the authenticated property of the state to true by dispatching another action, of the type AUTH_USER.

The LoginBar links to /auth/github if the user is not logged in, so they can be authenticated via Github and then redirected to /login and eventually /profile/[github_id] . If the user is logged in, there is a button that logs the user out by removing the token in localStorage.

Http requests:

Http Requests for which the user to be authenticated, are made from the ItemEdit component and the ItemTile component (Delete action), either dispatching the editItem and addItem actions in src/actions/index.js, or, in case of deleting, through a direct XHR call to the API (needs refactoring!). In all cases we set an authorisation header value. Inside the editItem and addItem actions, we use axios for this:

 const request = axios.put(url, item, {
    headers: { 'authorization': localStorage.getItem('authtoken') }
  })

The src/actions/index.js file also contains the action creators for the logging in and out functionality.

The asynchronous actions make use of the redux-thunk middleware which allows to return a function instead of an object, and that way dispatch another action. This allows several actions to be chained.

export function loginUser(gitHubUser) {
  const url = `${ROOT_URL}/checkUser/${gitHubUser}`
  const request = axios.get(url)
  return dispatch => {
    return request.then(
      resp => {                  
        dispatch({ type: types.AUTH_USER })
        localStorage.setItem("authtoken", resp.data.token)
        setTimeout(() => {
          browserHistory.push('/')},
          4000
        )
        return resp.data 
      }).catch(() => {
        dispatch(authError('Login did not succeed'))
    })
  }
}