bkn-auth
v3.1.2
Published
Authorization management and authentication checking for react apps.
Downloads
32
Readme
bkn-auth
Authorization management and authentication checking for react/redux apps.
Wait a minute. Authentication checking? What you mean by that?
Well. The complete authentication management is a concern of Account app. So other apps DO NOT know how to login a user, but they check if a token is still valid.
bkn-auth uses some High Order Components (HOCs) and all processes are orchestrated by redux and redux-saga. So this library have things like decorators, actions, reducers and sagas.
So, let's rock!
Table of Contents
Features
- Authorization by roles and teams
- Checks token expiration periodically
- Injects some special props in container components
- Wired to the store by actions dispatchs
Installation
npm install -S -E bkn-auth
Or using yarn.
yarn add -E bkn-auth
It has some peer dependencies, so if you not installed them, you have to.
yarn add -E redux redux-saga bkn-ui
Note: check Installtion section in bkn-ui repo for more details.
Getting Started
Authentication checking
Start by forking authenticationFlow
saga. You'll need to pass domain and account app url as parameters.
import {fork} from 'redux-saga/effects';
import {sagas as bknAuthSagas} from 'bkn-auth';
const domain = 'localhost';
const accountAppUrl = 'http://localhost:9000';
export function* rootSaga() {
yield fork(bknAuthSagas.authenticationFlow, domain, accountAppUrl);
// other sagas
}
authenticationFlow
saga will check periodically if authentication token is valid. If not, it will dispatch an action to update tokenExpired
property in global state. But a dispatch of an action without a reducer is useless. So let's include some reducers.
import {reducers as bknAuthReducers} from 'bkn-auth';
export const rootReducer = combineReducers({
// other reducers
...bknAuthReducers,
});
This will include our reducers and tokenExpired
and user
properties will be available in global state. These reducers will catch our actions dispatched in the previous step.
IMPORTANT: bkn-auth reducers have to be included in root reducer. Do not include them inside any redux modules of your application.
Note: see Reducers section for more details.
Ok. Now we have our global state updating automatically. But what to do in UI level if token expires? Let's use the authenticationRequired
HOC.
import {authenticationRequired} from 'bkn-auth';
@authenticationRequired
export class SomeTopLevelComponent extends React.Component {
// some code
}
authenticationRequired
will read the tokenExpired
property from global state. If token is expired, it opens a modal informing user that his session expired. This modal have a LOGIN button. User can click on it to be redirected to login page or if user login in another tab (in the same browser), modal will be dismissed.
Tip: use authenticationRequired
in a top level component. It's not necessary to use it in every page or route level container component.
Note: do not forget to import ConfirmModal
styles from bkn-ui to present modal in a properly way.
// Layout.scss
@import "node_modules/bkn-ui/scss/components/confirm-modal";
So, authentication checking is configured. For the last part of this getting started, let's see how to manage authorization. If your application doesn't need authorization, we finish here. If so, keep reading.
Authorization
We have a special HOC for it as well: authorize
. Let's see an example:
import {authorize} from 'bkn-auth';
// ListPage.js
@authorize({roles: ['editor']})
export class ListPage extends React.Component {
// some code
}
// FormPage.js
@authorize({teams: ['sales']})
export class FormPage extends React.Component {
// some code
}
As you can see, ListPage can only be accessed by users with editor role. FormPage, only by sales team.
admin is the default role. So if user is admin, he can access all pages. You don't need to use authorize
HOC at all.
So based on above example, if a user with author role try to access ListPage, authorize
will dispatch a redirectNotAuthorizedUser
action. Thus you can redirect user to a specific route. Let's listen for this action by using takeLatest
effect from redux-saga
.
import {takeLatest} from 'redux-saga/effects';
import {push} from 'react-router-redux';
import {actions as bknAuthActions} from 'bkn-auth';
function* navigateToHomePage() {
yield put(push('/home'));
}
export function* rootSaga() {
// other sagas
yield takeLatest(bknAuthActions.redirectNotAuthorizedUser, redirectToHomePage);
}
Note: as you can see, we can use put
effect from react-router-redux to change route from a saga. But be aware, react-router-redux is not related to this library.
And... that's it! You can see more details is next section, API Reference.
API Reference
Contributing
Create an issue describing clearly the new feature or problem.
Create a branch with issue name.
Improve/Fix it.
Generate bundle and types by running:
npm run build
Bump version in package.json based on SemVer.
Create a PR and inform what issue is closed. For example:
Closes #1
Approve and merge PR.
Delete branch.
Publish to npm:
npm publish
Create a tag for current version. For example:
git tag 1.0.0
Push tag to Github.
git push --tags
Write change log in tag body based on merged PRs. Example here.
Be happy. =]