-
Notifications
You must be signed in to change notification settings - Fork 13
Authentication ctd app implementation
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.
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 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'))
})
}
}