go-auth-w-mongo

command module
v0.0.0-...-509c4cf Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 7, 2020 License: MIT Imports: 10 Imported by: 0

README

GoDoc GoReportCard CircleCI

Go Auth App

Simple session based authentication with Mux and MongoDB

This repository was created as an exercise in Go development. This serves as a barebones boilerplate for a webapp that requires authentication via a database.

Setup

You can build the binary by running go build and run it via ./go-auth-w-mongo

Please make sure you have a local MongoDB instance running before attempting to run anything here! A simple auth flow may look something like this

  1. User attempts to access dashboard
  2. User is redirected to log in
  3. User logs in and is redirected to dashboard
  4. (Admin only) Admin can add a new user

The following routes have been implemented:

/register "register a new user"
/login "authenticates a user"
/dashboard "simple dashboard to display user's name"
/logout "destroys current user's session"
/register

The /register endpoint first checks to see if the user has a valid session (this is done through the authentication middleware in middleware/middleware.go) and is an admin.

Then, it attempts to parse the form data into the User schema. After doing so, a hash is generated from the password to avoid storing it in plaintext, and the document is inserted into the database.

curl --location --request POST 'localhost:8080/register' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'email=test@email.com' \
--data-urlencode 'name=jacky' \
--data-urlencode 'password=pass123'
/login

The /login endpoint attempts to decode the form data into the Credentials schema. Then, it attempts to find a user with a matching email in the database. If found, it compares the password hashes to see if the password is correect. If so, it will create a new session token, write that to both the client (as a cookie) and the database (as a document), and redirect them to /dashboard

curl --location --request POST 'localhost:8080/login' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'email=test@email.com' \
--data-urlencode 'password=pass123'
/dashboard

The /dashboard endpoint takes advantage of the fact that our middleware injects a header called X-res-email with the user's email if the user has a valid session. This is a basic endpoint that returns a custom greeting based on the user's name.

curl --location --request GET 'localhost:8080/dashboard'
/logout

The /logout also uses the X-res-email header to make the logout code super simple and short. Basically, it just resets the user's session on the database side, so auth will redirect to login.

curl --location --request GET 'localhost:8080/logout'

Adding to the project

As this is just a boilerplate, this project is meant to be easily extensible. Feel free to add more endpoints in routes/routes.go, render and serve templates, and add more middleware! The project is your oyster :)

FAQ

How does session based authentication work?

This photo (courtesy of PracticalDev) does a pretty good job at explaining it!

Session Based Auth

Adding an admin user

Remove the admin checker middleware from server.go register endpoint by changing line 22 from

r.HandleFunc("/register", middleware.Auth(routes.Register, true))

to

r.HandleFunc("/register", routes.Register)

Then, make a POST request to the /register endpoint with a x-www-form-urlencoded (form data) with the required fields. Make sure to set the admin field to true!

It would look something like this

curl --location --request POST 'localhost:8080/register' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'email=test@email.com' \
--data-urlencode 'name=jacky' \
--data-urlencode 'password=pass123' \
--data-urlencode 'admin=true'

Don't forget to change that line back later.

Changing URL of database

This is set in routes/routes.go line 19,

var session, _ = mgo.Dial("mongodb://localhost:27017")
Changing name of database used and name of collection

This is set in routes/routes.go line 22,

// "exampleDB" is the name of the database
// "Users" is the name of the collection
var Users = session.DB("exampleDB").C("Users")
Other types of database connections

Edit db/db.go and change const DB_TYPE to something else.

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
Package middleware defines possible middleware that can be used by the router.
Package middleware defines possible middleware that can be used by the router.
Package routes defines routes for the app
Package routes defines routes for the app
Schema Definitions for MongoDB Documents
Schema Definitions for MongoDB Documents

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL