• Stars
    star
    386
  • Rank 110,749 (Top 3 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created almost 9 years ago
  • Updated about 7 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Redux JWT Authentication Sample

This is a sample of how to implement JWT authentication in React and Redux apps. It uses Auth0's NodeJS JWT Authentication Sample to authenticate users and retrieve quotes from a protected endpoint.

The sample is well-informed by the official Redux examples.

Check the auth0-lock branch for the Auth0 specific version

Installation

Clone the repo and run the installation commands, each in a new terminal window.

# Get the server submodule
git submodule update --init

# Install deps in the project root and in the server directory
npm install
cd server && npm install
cd ..

# Run the server
npm run server

# New terminal window
npm start

The app will be served at localhost:3000.

Important Snippets

Users are authenticated by making a fetch request to localhost:3001/sessions/create. We have actions setup for this.

// actions.js

// There are three possible states for our login
// process and we need actions for each of them
export const LOGIN_REQUEST = 'LOGIN_REQUEST'
export const LOGIN_SUCCESS = 'LOGIN_SUCCESS'
export const LOGIN_FAILURE = 'LOGIN_FAILURE'

function requestLogin(creds) {
  return {
    type: LOGIN_REQUEST,
    isFetching: true,
    isAuthenticated: false,
    creds
  }
}

function receiveLogin(user) {
  return {
    type: LOGIN_SUCCESS,
    isFetching: false,
    isAuthenticated: true,
    id_token: user.id_token
  }
}

function loginError(message) {
  return {
    type: LOGIN_FAILURE,
    isFetching: false,
    isAuthenticated: false,
    message
  }
}

// Three possible states for our logout process as well.
// Since we are using JWTs, we just need to remove the token
// from localStorage. These actions are more useful if we
// were calling the API to log the user out
export const LOGOUT_REQUEST = 'LOGOUT_REQUEST'
export const LOGOUT_SUCCESS = 'LOGOUT_SUCCESS'
export const LOGOUT_FAILURE = 'LOGOUT_FAILURE'

function requestLogout() {
  return {
    type: LOGOUT_REQUEST,
    isFetching: true,
    isAuthenticated: true
  }
}

function receiveLogout() {
  return {
    type: LOGOUT_SUCCESS,
    isFetching: false,
    isAuthenticated: false
  }
}

// Calls the API to get a token and
// dispatches actions along the way
export function loginUser(creds) {
  
  let config = {
    method: 'POST',
    headers: { 'Content-Type':'application/x-www-form-urlencoded' },
    body: `username=${creds.username}&password=${creds.password}`
  }
  
  return dispatch => {
    // We dispatch requestLogin to kickoff the call to the API
    dispatch(requestLogin(creds))
    return fetch('http://localhost:3001/sessions/create', config)
      .then(response =>
        response.json()
        .then(user => ({ user, response }))
      ).then(({ user, response }) =>  {
        if (!response.ok) {
          // If there was a problem, we want to
          // dispatch the error condition
          dispatch(loginError(user.message))
          return Promise.reject(user)
        }
        else {
          // If login was successful, set the token in local storage
          localStorage.setItem('id_token', user.id_token)
          
          // Dispatch the success action
          dispatch(receiveLogin(user))
        }
      }).catch(err => console.log("Error: ", err))
  }
}

// Logs the user out
export function logoutUser() {
  return dispatch => {
    dispatch(requestLogout())
    localStorage.removeItem('id_token')
    dispatch(receiveLogout())
  }
}

We also have actions for retreiving the quotes that uses an API middleware.

// middleware/api.js

const BASE_URL = 'http://localhost:3001/api/'

function callApi(endpoint, authenticated) {
  
  let token = localStorage.getItem('id_token') || null
  let config = {}
  
  if(authenticated) {
    if(token) {
      config = {
        headers: { 'Authorization': `Bearer ${token}` }
      }
    } else {
      throw "No token saved!"
    }
  }
  
  return fetch(BASE_URL + endpoint, config)
    .then(response =>
      response.text()
      .then(text => ({ text, response }))
    ).then(({ text, response }) => {
      if (!response.ok) {
        return Promise.reject(text)
      }
      
      return text
    }).catch(err => console.log(err))
}

export const CALL_API = Symbol('Call API')

export default store => next => action => {
  
  const callAPI = action[CALL_API]
  
  // So the middleware doesn't get applied to every single action
  if (typeof callAPI === 'undefined') {
    return next(action)
  }
  
  let { endpoint, types, authenticated } = callAPI
  
  const [ requestType, successType, errorType ] = types
  
  // Passing the authenticated boolean back in our data will let us distinguish between normal and secret quotes
  return callApi(endpoint, authenticated).then(
    response =>
      next({
        response,
        authenticated,
        type: successType
      }),
    error => next({
      error: error.message || 'There was an error.',
      type: errorType
    })
  )
}
// actions.js

// Uses the API middlware to get a quote
export function fetchQuote() {
  return {
    [CALL_API]: {
      endpoint: 'random-quote',
      types: [QUOTE_REQUEST, QUOTE_SUCCESS, QUOTE_FAILURE]
    }
  }
}

// Same API middlware is used to get a 
// secret quote, but we set authenticated
// to true so that the auth header is sent
export function fetchSecretQuote() {
  return {
    [CALL_API]: {
      endpoint: 'protected/random-quote',
      authenticated: true,
      types: [QUOTE_REQUEST, QUOTE_SUCCESS, QUOTE_FAILURE]
    }
  }
}

The reducers return new objects with the data carried by the actions.

// reducers.js

import { combineReducers } from 'redux'
import { 
  LOGIN_REQUEST, LOGIN_SUCCESS, LOGIN_FAILURE, LOGOUT_SUCCESS,
  QUOTE_REQUEST, QUOTE_SUCCESS, QUOTE_FAILURE
} from './actions'

// The auth reducer. The starting state sets authentication
// based on a token being in local storage. In a real app,
// we would also want a util to check if the token is expired.
function auth(state = {
    isFetching: false,
    isAuthenticated: localStorage.getItem('id_token') ? true : false
  }, action) {
  switch (action.type) {
    case LOGIN_REQUEST:
      return Object.assign({}, state, {
        isFetching: true,
        isAuthenticated: false,
        user: action.creds
      })
    case LOGIN_SUCCESS:
      return Object.assign({}, state, {
        isFetching: false,
        isAuthenticated: true,
        errorMessage: ''
      })
    case LOGIN_FAILURE:
      return Object.assign({}, state, {
        isFetching: false,
        isAuthenticated: false,
        errorMessage: action.message
      })
    case LOGOUT_SUCCESS:
      return Object.assign({}, state, {
        isFetching: true,
        isAuthenticated: false
      })
    default:
      return state
    }
}

// The quotes reducer
function quotes(state = {
    isFetching: false,
    quote: '',
    authenticated: false
  }, action) {
  switch (action.type) {
    case QUOTE_REQUEST:
      return Object.assign({}, state, {
        isFetching: true
      })
    case QUOTE_SUCCESS:
      return Object.assign({}, state, {
        isFetching: false,
        quote: action.response,
        authenticated: action.authenticated || false
      })
    case QUOTE_FAILURE:
      return Object.assign({}, state, {
        isFetching: false
      })
    default:
      return state
  }
}

// We combine the reducers here so that they
// can be left split apart above
const quotesApp = combineReducers({
  auth,
  quotes
})

export default quotesApp

What is Auth0?

Auth0 helps you to:

  • Add authentication with multiple authentication sources, either social like Google, Facebook, Microsoft Account, LinkedIn, GitHub, Twitter, Box, Salesforce, amont others, or enterprise identity systems like Windows Azure AD, Google Apps, Active Directory, ADFS or any SAML Identity Provider.
  • Add authentication through more traditional username/password databases.
  • Add support for linking different user accounts with the same user.
  • Support for generating signed Json Web Tokens to call your APIs and flow the user identity securely.
  • Analytics of how, when and where users are logging in.
  • Pull data from other sources and add it to the user profile, through JavaScript rules.

Create a Free Auth0 Account

  1. Go to Auth0 and click Sign Up.
  2. Use Google, GitHub or Microsoft Account to login.

Issue Reporting

If you have found a bug or if you have a feature request, please report them at this repository issues section. Please do not report security vulnerabilities on the public GitHub issue tracker. The Responsible Disclosure Program details the procedure for disclosing security issues.

Author

Auth0

License

This project is licensed under the MIT license. See the LICENSE file for more info.

More Repositories

1

angular2-authentication-sample

This is a sample that shows how to add authentication to an Angular 2 (ng2) app
JavaScript
970
star
2

nodejs-jwt-authentication-sample

A NodeJS API that supports username and password authentication with JWTs
JavaScript
689
star
3

react-flux-jwt-authentication-sample

Sample for implementing Authentication with a React Flux app and JWTs
JavaScript
590
star
4

vue-jwt-authentication

Vue
506
star
5

angular-token-auth

Token-based authentication in AngularJS
JavaScript
361
star
6

angularjs-jwt-authentication-tutorial

Demo for ngEurope's talk
JavaScript
214
star
7

angular2-electron

TypeScript
169
star
8

angular2-the-new-horizon-sample

Sample project for Angular 2: The new horizon talk at jQuerySF
JavaScript
150
star
9

vuejs2-authentication-tutorial

JavaScript
145
star
10

reactjs-authentication-tutorial

Chuck Norris World App - A sample app that shows how to add authentication to a ReactJS app
JavaScript
140
star
11

angular-2-authentication-tutorial

TypeScript
104
star
12

sqlalchemy-orm-tutorial

Repository that accompanies the "SQLAlchemy ORM Tutorial for Python Developers" blog post
103
star
13

mean-rsvp-auth0

MEAN stack application with Auth0 (see sample deployed at https://rsvp.kmaida.net)
TypeScript
98
star
14

auth0-golang-jwt

Authenticate a Golang API with JSON Web Tokens (JWT)
JavaScript
97
star
15

actix-diesel-auth

A demo of using actix, disel for authentication using Auth0
Rust
82
star
16

django-vue.js

Securing Django and Vue.js Applications with Auth0
JavaScript
81
star
17

angular-auth0-aside

Aside: Angular with Auth0 and an authenticated Node API.
TypeScript
80
star
18

react-tutorial

JavaScript
76
star
19

mfa-and-microservices-blog-samples

JavaScript
75
star
20

python-flask-angular-1

Repository for the "Using Python, Flask, and Angular to Build Modern Web Apps - Part 1" article
TypeScript
67
star
21

flutter-authentication

Get Started with Flutter Authentication
Dart
65
star
22

nextjs-passport

JavaScript
64
star
23

flask-restful-apis

Project created throughout the "Developing RESTful APIs with Python and Flask" article.
Python
63
star
24

nest-react-blog-ga

TypeScript
63
star
25

react-rbac

Role-Based Access Control (RBAC) and React Apps
JavaScript
62
star
26

webtask-runner

A server that runs WebTasks.
JavaScript
61
star
27

aliens-go-home-part-1

GitHub repository that accompanies the first article of the "Developing Games with React, Redux, and SVG" series.
JavaScript
60
star
28

react-flux-debug-actions-sample

This repository shows how you can use Flux actions to reproduce your user's issues in your own browser
JavaScript
59
star
29

jwt-as-api-keys

Example of how to use JWTs as API Keys
JavaScript
58
star
30

elm-with-jwt-api

Elm
57
star
31

auth0-python-fastapi-sample

Code sample for a protected API in FastAPI for Python
Python
56
star
32

blog-refresh-tokens-sample

Refresh tokens example for blog post
JavaScript
53
star
33

questionmarks-server

Java
50
star
34

serverless-stories-lambda

Serverless app built with AWS Lambda
JavaScript
50
star
35

gatsby-auth0

Sample code for adding Auth0 to a Gatsby site. Can also be used as a Gatsby starter.
JavaScript
47
star
36

vue-express-auth

JavaScript
47
star
37

spring-boot-jwts

Securing Spring Boot with JWTs
Java
46
star
38

go-react-vr

Create a voting application with Go and React
JavaScript
46
star
39

book-app

JavaScript
44
star
40

spring-boot-auth

Developing and Securing RESTful APIs with Spring Boot
Java
44
star
41

falcor-create-demo

falcor-create-demo
JavaScript
43
star
42

hapi-jwt-authentication

JavaScript
41
star
43

secure-blazor-wasm-quiz-manager

HTML
40
star
44

auth0-react-sample

React project that defines a Single-Page Application (SPA)
JavaScript
40
star
45

pet-tags-ngrx

TypeScript
39
star
46

react-auth0

JavaScript
39
star
47

auth0-express

JavaScript
39
star
48

electron-openid-oauth

JavaScript
38
star
49

nodejs-awesome-polls

JavaScript
38
star
50

rust-api-example

Example of a RESTful API in Rust
Rust
37
star
51

sails-jwt-authentication-tutorial

A SailsJS API that supports username and password authentication with JWTs
JavaScript
36
star
52

nextjs-got

A simple nextjs application that showcases Game of Thrones Characters
JavaScript
32
star
53

blazor-quiz-manager

HTML
32
star
54

spring-boot-faces

Java
32
star
55

relay-auth

Code sample of the Auth0 Relay tutorial
JavaScript
31
star
56

bff-auth0-dotnet

C#
31
star
57

vue-events-auth

Vue
31
star
58

ionic-audio-player

TypeScript
29
star
59

lumen-api-auth

Lumen Authors API. Secured with JWT
PHP
29
star
60

polymer-with-jwt-api

Build an app using web components and Polymer with an API and JSON Web Token authentication.
HTML
29
star
61

ngrx-auth

Sample code for adding authentication to an NgRx project.
TypeScript
29
star
62

streamlit-asehmi

Python
28
star
63

fireteller

FireTeller is a Firebase app that integrates Auth0 for user authentication.
JavaScript
28
star
64

blog-dombench

DOM benchmarks using different libraries
JavaScript
27
star
65

blog-passwordless-authentication

Learn how to integrate passwordless authentication with Facebook Account Kit and Auth0 Passwordless
JavaScript
26
star
66

golang-angular

Go
25
star
67

nest-restaurant-api

TypeScript
25
star
68

redux-auth0

JavaScript
24
star
69

rottentomatoes-clone

JavaScript
24
star
70

glossary-web-api-aspnet-core

C#
24
star
71

cordova-sample

Sample for the post: https://auth0.com/blog/2015/12/08/converting-your-web-app-to-mobile/
Java
24
star
72

angular-auth

JavaScript
24
star
73

angular2-http

Code for the Angular 2 Http tutorial
TypeScript
24
star
74

grpc-dotnet

C#
23
star
75

blog-ldap-csharp-example

C#
23
star
76

glossary-web-api-aspnet

C#
22
star
77

jwts-in-python

Check out how to create and validate JWTs in Python
22
star
78

aliens-go-home-part-3

GitHub repository that accompanies the third article of the "Developing Games with React, Redux, and SVG" series.
JavaScript
22
star
79

next6-auth0

JavaScript
22
star
80

cookie-jwt-auth

Example of how to use JWTs in cookies
JavaScript
22
star
81

auth0-angular-sample

Angular project that defines a Single-Page Application (SPA)
TypeScript
21
star
82

springboot-auth-updated

Implementing JWT Authentication on Spring Boot APIs
Java
21
star
83

auth0-graphql-server

JavaScript
21
star
84

ionic2-auth

TypeScript
21
star
85

angular-d3-socketio

TypeScript
20
star
86

nest-companies

TypeScript
20
star
87

firebase-auth0-nodeserver

Node.js server that mints custom Firebase tokens and serves dog breed data.
JavaScript
20
star
88

angular-material

Creating Beautiful Apps with Angular Material
TypeScript
20
star
89

nodejs-restify

JavaScript
20
star
90

auth0-hooks-context

JavaScript
19
star
91

es2015-rundown-example

JavaScript
19
star
92

kotlin-spring-boot

RESTful APIs with Kotlin and Spring Boot
Shell
19
star
93

next2-auth0

JavaScript
18
star
94

spa-jwt-authentication-tutorial

Add authentication to a vanilla js single page app
JavaScript
18
star
95

firebase-phone-auth

Firebase Phone Number Authentication
JavaScript
18
star
96

svelte-auth0

JavaScript
18
star
97

ethereum-login-sample

Ethereum Login example for second Ethereum post
JavaScript
18
star
98

angular2-routing

JavaScript
18
star
99

auth0-express-js-sample

Express API to showcase Auth0 API authorization.
JavaScript
17
star
100

kotlin-graphql

Kotlin
16
star