npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@gggdomi/rrh-auth

v0.3.5

Published

Plugin for RRH to help with authentication workflow. Store credentials, authenticate requests and redirect to login if needed.

Downloads

19

Readme

Plugin for RRH to help with authentication workflow. Store credentials, authenticate requests and redirect to login if needed.

Installation

Pre-requisites

  • RRH need to be set up
  • connected-react-router is required to be able to change location by dispacthing action. It's a drop-in replacement for react-router and might be of use if you mix react-router with redux in your project.

yarn add @gggdomi/rrh-auth

Add to RRH plugins

// index.js
import rrh from '@gggdomi/rrh'
import rrhAuth from '@gggdomi/rrh-auth'

rrh.plugins = [rrhAuth]

Add auth reducer

// reducers.js
import { rrhReducers } from '@gggdomi/rrh' // from RRH readme
import { authReducer } from '@gggdomi/rrh-auth'

export const rootReducer = combineReducers({
    your: yourReducer,
    rrh: combineReducers(rrhReducers), // from RRH readme
    auth: authReducer,
  })

Add rrh-auth sagas to the app

// index.js
import rrhAuthSagas from '@gggdomi/rrh-auth/src/sagas'

// configure saga middleware...

rrhAuthSagas.map(sagaMiddleware.run)

Tell which server-side endpoints are used to login

isLoginEndpoint will tell rrh-auth to look for credentials when calling these endpoints

import rrh from '@gggdomi/rrh'

export const postLogin = rrh.new('SUBMIT_LOGIN', '/login/', {
  method: 'POST',
  isLoginEndpoint: true, // here
})

Usage

Dispatch actions to log in/out

import { logOutAction } from '@gggdomi/rrh-auth'
import { postLogin } from './actions'

const ExComponent = ({ triggerLogOut }) => (
  <button onClick={triggerLogIn}>Log in</button>
  <button onClick={triggerLogOut}>Log out</button>
)

const mapDispatchToProps = dispatch => ({
  triggerLogIn: () => dispatch(postLogin.Start({  
    // using postLogin route created above
    data: {user: "John", pass: "123456" }
  })),
  triggerLogOut: () => dispatch(logOutAction()),
})

export default connect(null, mapDispatchToProps)(ExComponent)

Configuration

Right now rrh-auth only supports authentication via JWT tokens and Authorization header. Other authentication means could easily be added, feel free to open an issue if needed.

// rrhAuth.config:
{
  jwt: {
    // to use rrh-auth with jwt (default: true)
    use: true,
    
    // how to extract JWT token from the server response
    getToken: data => data.access_token,  // <- default value
    
    // how to create the Authorization header given the token
    makeAuthHeader: accessToken => 'Bearer ' + accessToken, // <- default value
    
    // how to extract user infos from decoded token
    getInfos: data => data.identity, // <- default value
  },

  // set to true to automatically logout when getting a 401 status (ie. invalid/missing credentials) (default: true)
  shouldLogoutOn401: true,
  
  // if not null, we push this URL (default: '/')
  redirectToOnLoggedIn: '/home/',
  
  // if not null, set to true to automatically display login page when logging out (default: '/login/')
  loginRoute: '/login/',
  
  // if not null, this endpoint will be called on the server when logging out (default: '/logout/')
  logoutEndpoint: '/logout/',
}

Example:

Let's say your API:

  • on successful login (POST on '/login/'), the server returns a response containing a token { apiToken: "xxxxxxxxxxxx" }
  • is authenticated via Authorization header, with format "Token xxxxxxxxxxxxx".
  • once decoded, the user infos are available on the infos property of the token
  • you need to GET /destroy/ to logout serverside

To configure rrh-auth accordingly:

import rrhAuth from '@gggdomi/rrh-auth'

rrhAuth.config.jwt.getToken = data => data.apiToken
rrhAuth.config.jwt.makeAuthHeader = token => `Token ${token}`
rrhAuth.config.jwt.getInfos = x => x.infos
rrhAuth.config.logoutEndpoint = '/destroy/'

Routes options

import rrh from '@gggdomi/rrh'

export const fetchPosts = rrh.new('FETCH_POSTS', '/posts/', {
  // will tell rrh-auth to look for credentials when calling these endpoints (default: false)
  isLoginEndpoint: false,
  
  // if set to true, we won't redirect to login for this route if we get a 401 from server (default: false)
  ignore401: true, 

  // if set to false, we won't attach token to request (default: true)
  authenticated: false,
})

Advanced customization

Redirection to login page on logout or invalid credentials, and calling a server endpoint on logout are built in rrh-auth by default. If you need more specific behavior, you can set loginRoute and logoutEndpoint to null and then take logOutAction and loggedInAction in your own sagas

Example:

import { logOutAction, loggedInAction } from '@gggdomi/rrh-auth'
import { push } from 'connected-react-router'

export function* loggedInSaga() {
  yield takeEvery(loggedInAction().type, function*(action) {
    // We do some stuff and redirect to root on successful login
    doSomeStuff()
    yield put(push('/'))
  })
}

export function* logOutSaga() {
  yield takeEvery(logOutAction().type, function*(action) {
    // we do some stuff on logout
    doSomeStuff()
  })
}

// don't forget to then run the sagas