• Stars
    star
    110
  • Rank 316,770 (Top 7 %)
  • Language
    Go
  • License
    MIT License
  • Created over 8 years ago
  • Updated about 5 years ago

Reviews

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

Repository Details

This is an example implementation of jwt auth with goLang

goLang-jwt-auth-example

This is an example implementation of jwt auth with goLang. Please note that I am not an expert in this field and am creating this repository more for a learning experience than anything else. I hope to learn a lot from this experience and am sharing my work so that you might learn, too.

Also, this isn't an exmaple of how to structure a web app or how to map and handle authorized / un-authorized routes, etc.

FYI - I'm using goDep

Goals

It is important to understand the objective of this auth architecture. It certainly is not an applicable design for all use cases. Please read and understand the goals, below, and make changes to your own workflow to suit your specific needs.

  1. Protection of non-critical api's (e.g. not meant for financial, healthcare, gov't, etc. services)
  2. Stateless
  3. User sessions
  4. XSS protection
  5. CSRF protection
  6. Web (but could be easily modified for use in mobile / other. i.e. for native mobile don't use cookies but rather the proper, secure storage methods for your platform)

Basics

The design of this auth system is based around the three major components, listed below.

  1. Short-lived (minutes) JWT Auth Token
  2. Longer-lived (hours / days) JWT Refresh Token
  3. CSRF secret string

Once a user provides valid login credentials, they are sent back the three items listed above.

1. Short-lived (minutes) JWT Auth Token

The short-lived jwt auth token allows the user to make stateless requests to protected api endpoints and lives in an http only cookie on the client. It has an expiration time in minutes and will be refreshed by the longer-lived refresh token. This token contains the following claims:

  • sub [uuid]: the subject (user) who has requested this claim.
  • exp [timestamp]: the date/time the token expires (I'm using 15 minutes in this example. Adjust as you see fit)
  • role [string]: One of "admin" or "user"
  • csrf [string]: A random string to be used to protect against csrf attacks

2. Longer-lived (hours/days) JWT Refresh Token

This longer-lived token will be used to update the auth tokens. These tokens will also live in http only cookies on the client. These tokens have a 72 hour expiration time which will be updated each time an auth token is refreshed. If a client tries to use an expired refresh token, they will be re-directed to a login page.

These refresh tokens contain an id which can be revoked by an authorized client.

The claims of this refresh token include:

  • jti [uuid]: a unique string to identify this token
  • sub [uuid]: the subject (userId) who has requested this claim.
  • exp [timestamp]: the date/time the token expires (I'm using 72 hours in this example. Adjust as you see fit)

3. CSRF Secret String

A CSRF secret string will be provided to each client and will be identical the CSRF secret in the auth token and will change each time an auth token is refreshed. These secrets will live in an "X-CSRF-Token" response header. These secrets will be sent along with the auth and refresh tokens on each api request. They will be sent to the server either as a hidden form value or in the request header. This secret will be checked against the secret provided in the auth token in order to prevent CSRF attacks.

Auth Flow

Sign In

  1. User provides a username and password
  2. Password is SHA256 hashed on the client before being sent to the server (never simply rely on https and send plaintext passwords over the wire!!)
  3. SHA256 password hash is bcrypted and checked against the database
  4. If a match is found, an auth token, refresh token and CSRF secret is created and sent back to the client. The refresh token's JTI is stored in the db.
    • The auth token and refresh tokens are kept in http only cookies
    • The CSRF secret is sent in the response header, with a key of "X-CSRF-Token"

Restricted API request

  1. Client adds the CSRF token to the request header with the key "X-CSRF-Token" (can also be sent as a hidden form value)
  2. The auth token is checked:
    • First, the csrf secret from the request header is matched to the secret in the auth jwt
    • Second, the token expiration time is checked:
      • If not expired, the request is allowed
      • If expired, a new auth token is issued from the refresh token. The refresh token expiration is checked, and the JTI checked against the db. If both checks pass, a new auth token is generated. If either check fails, the request fails and the user is asked to log back in.
  3. Finally, if successful, a new csrf secret is generated and stored in the newly created auth token. Also, the refresh token expiration time is reset.
  4. The auth token, refresh token and csrf secret are sent back to the client as described, above.

Sign out

  1. Signout is a restricted route, so the client must provide an auth token, refresh token and csrf secret. They are checked as described, above.
  2. The refresh token JTI is removed from the whitelisted list of valid JTI's in our db
  3. The client's auth and refresh tokens are nullified (their values are set to "")

More Repositories

1

jwt-auth

This package provides json web token (jwt) middleware for goLang http servers
Go
231
star
2

arrayOperations

Small library for performing union, intersect, difference and distinct operations on slices in goLang
Go
89
star
3

sessions

A dead simple, highly performant, highly customizable sessions middleware for go http servers.
Go
77
star
4

react-responsive-tables

A react component for responsive tables
JavaScript
52
star
5

goal-seek

goal-seek is a javascript library that can be used to solve for the value of an independent variable: "x"; of a function: "f(x)"; such that f(x) equals some defined goal. In other words: do you know the desired output of a function but not the input to yield such an output? If so, then use this goal seek!
TypeScript
36
star
6

design-first

A REST api templating engine for typescript.
TypeScript
34
star
7

golang-vuejs-starter-kit

This is a starter kit for goLang and vuejs which can be cloned to start your next project
JavaScript
29
star
8

lwan-mustache-c

The mustache templating engine from the lwan http server written in C
C
8
star
9

securitiesOption.js

securitiesOption.js is a javascript library for evaluating option prices and implied volatilities using Cox Ross Rubinstein (CRR), trinomial trees or Black-Scholes
JavaScript
8
star
10

PDQdb

A read-optimized, in-memory, columnar store database (column-oriented DBMS)
Go
5
star
11

c-vs-goLang-Quicksort

Testing the performance of quicksort in c and goLang
C
5
star
12

httb

An http benchmarking tool written in go
Go
3
star
13

design-first-example

Example with postgres, redis, and passport.js sessions
TypeScript
3
star
14

redis-sessions

A plugin for github.com/RichardKnop/go-oauth2-server that provides redis storage for sessions
Go
2
star
15

vue-router-cordova

A non-working example of vue v2, vue-router and cordova
JavaScript
1
star
16

randomStrings

Generate random strings in goLang
Go
1
star
17

btc_address_validator

A BTC public address validator sourced from rosettacode.org
Go
1
star
18

vgo-bug

Demo repo of a bug in vgo
Go
1
star
19

gretl

A fork of the GNU Regression, Econometrics and Time-series Library (GRETL)
C
1
star
20

copyRecursive

Recursively copy structs in goLang
Go
1
star
21

McClaneScript

McClaneScript is a new syntax for javascript. Now, write all of your code with one-liners from John McClane in Die Hard!
JavaScript
1
star