auth

package module
v1.2.1 Latest Latest
Warning

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

Go to latest
Published: Nov 2, 2021 License: MIT Imports: 11 Imported by: 3

README

Golang HTTP authentication library, no catchy name.

This is a library I wrote when I found existing http auth libraries lacking in one area or another.
Not entirely documented yet, but I've pounded most of the kinks out and felt it was about time to share.

It's design is based on https://github.com/xyproto/permissionbolt/, initializing a 'state' that is passed
around to hold the boltDB connection and secureCookie instance.

Features:

  • Users and keys are stored inside a bboltdb
  • Cookies are authenticated and encrypted using gorilla/securecookie
    • The hash and block keys are generated upon DB initialization and stored in the auth.db
  • User registration and authentication
    • Passwords are hashed with bcrypt, using a work factor of 14
    • When logging in, a 128 character session ID is generated and stored in the DB and cookie
    • Optionally, one-time-use registration tokens can be required to sign up
  • Cross-site Request Forgery protection, using the gorilla/csrf library is integrated, storing the CSRF key in the same auth.db
  • Flash messages, stored inside a cookie and deleted once read
  • Built-in HTTP handlers are provided for some of the more agnostic POST requests, including:
    • LogoutHandler: clearing the session cookie
    • UserSignupPostHandler: provided a username and password form value, create a new user, and log that user in
    • UserSignupTokenPostHandler: provided a username, password, and register_key form value, validate the registration token, create a new user, and log that user in
    • LoginPostHandler: provided a username, and password form value, authenticate and log the user in
    • NewUserToken: generate a new registration token

Example:

There is a simple example application available in examples/simple/main.go, showing the basics of integrating this library into an application.

Documentation

Index

Constants

View Source
const (
	// UserKey is used to store the *User in the context
	UserKey key = 1
	// MsgKey is used to store flash messages in the context
	MsgKey key = 2
	// ChkKey is used to store whether UserEnvMiddle has been hit in the context
	ChkKey key = 3
)

Variables

View Source
var (
	// LoginPath is the path to the login page, used to redirect protected pages
	LoginPath = "/login"
	// SignupPath is the path to your signup page, used in the initial registration banner
	SignupPath = "/signup"
)

Functions

func CSRFTemplateField added in v1.0.2

func CSRFTemplateField(r *http.Request) template.HTML

CSRFTemplateField wraps gorilla/csrf.TemplateField

func CheckPasswordHash

func CheckPasswordHash(hash, password []byte) error

CheckPasswordHash securely compares a bcrypt hashed password with its possible plaintext equivalent. Returns nil on success, or an error on failure.

func HashPassword

func HashPassword(password []byte) ([]byte, error)

HashPassword generates a bcrypt hash of the password using work factor 14.

func Redirect

func Redirect(state *State, w http.ResponseWriter, r *http.Request)

Redirect throws the r.URL.Path into a cookie named "redirect" and redirects to the login page

Types

type DB

type DB struct {
	// contains filtered or unexported fields
}

DB wraps a bolt.DB struct, so I can test and interact with the db from programs using the lib, while vendoring bolt in both places

func (*DB) Auth

func (db *DB) Auth(username, password string) bool

Auth authenticates a given username and password

func (*DB) DeleteRegisterToken

func (db *DB) DeleteRegisterToken(token string)

DeleteRegisterToken deletes a registration token

func (*DB) DeleteSessionID added in v1.1.0

func (db *DB) DeleteSessionID(sessionID string)

DeleteSessionID deletes a given session ID

func (*DB) DeleteUser

func (db *DB) DeleteUser(username string) error

DeleteUser deletes a given user from the DB

func (*DB) DoesUserExist

func (db *DB) DoesUserExist(username string) bool

DoesUserExist checks if user actually exists in the DB

func (*DB) GenerateRegisterToken

func (db *DB) GenerateRegisterToken(role string) string

GenerateRegisterToken generates a token to register a user, and only a user

func (*DB) GetSessionID added in v1.1.0

func (db *DB) GetSessionID(sessionID string) string

GetSessionID checks for a given session ID in the DB and returns the associated username

func (*DB) NewAdmin

func (db *DB) NewAdmin(username, password string) error

NewAdmin creates a new admin with a given plaintext username and password

func (*DB) NewUser

func (db *DB) NewUser(username, password string) error

NewUser creates a new user with a given plaintext username and password

func (*DB) PutSessionID added in v1.1.0

func (db *DB) PutSessionID(username string) string

PutSessionID generates a session ID and ties the ID to the given user

func (*DB) UpdatePass

func (db *DB) UpdatePass(username string, hash []byte) error

UpdatePass updates a given user's password to the given hash Password hashing must be done by the caller

func (*DB) Userlist

func (db *DB) Userlist() ([]string, error)

Userlist lists all users in the DB

func (*DB) ValidateRegisterToken

func (db *DB) ValidateRegisterToken(token string) (bool, string)

ValidateRegisterToken validates that a given registration token is valid, exists inside the DB

type State

type State struct {
	DB
	// contains filtered or unexported fields
}

State holds all required info to get authentication working in the app

func NewAuthState

func NewAuthState(path string) *State

NewAuthState creates a new AuthState using the BoltDB backend, storing the boltDB connection and cookie info

func NewAuthStateWithDB

func NewAuthStateWithDB(db *DB, path string) *State

NewAuthStateWithDB takes an instance of a boltDB, and returns an AuthState using the BoltDB backend

func (*State) AnyUsers added in v1.0.10

func (state *State) AnyUsers() bool

AnyUsers checks if there are any users in the DB This is useful in application initialization flows

func (*State) AuthAdminMiddle

func (state *State) AuthAdminMiddle(next http.HandlerFunc) http.HandlerFunc

AuthAdminMiddle is a middleware to protect a given handler; admin only access

func (*State) AuthMiddle

func (state *State) AuthMiddle(next http.HandlerFunc) http.HandlerFunc

AuthMiddle is a middleware for HandlerFunc-specific stuff, to protect a given handler; users only access

func (*State) AuthMiddleHandler

func (state *State) AuthMiddleHandler(next http.Handler) http.Handler

AuthMiddleHandler is a middleware to protect a given handler; users only access

func (*State) CSRFProtect added in v1.0.2

func (state *State) CSRFProtect(secure bool) func(http.Handler) http.Handler

CSRFProtect wraps gorilla/csrf.Protect, only allowing toggling the Secure option

func (*State) GetFlash added in v1.1.0

func (state *State) GetFlash(r *http.Request, w http.ResponseWriter) string

GetFlash retrieves token from context

func (*State) GetRedirect added in v1.1.0

func (state *State) GetRedirect(r *http.Request, w http.ResponseWriter) (redirURL string)

GetRedirect returns the URL from the redirect cookie

func (*State) GetUserState added in v1.1.0

func (state *State) GetUserState(r *http.Request) *User

GetUserState returns a *User from the context The *User should have been crammed in there by UserEnvMiddle

func (*State) IsLoggedIn added in v1.1.0

func (state *State) IsLoggedIn(r *http.Request) bool

IsLoggedIn takes a context, tries to fetch user{} from it,

and if that succeeds, verifies the username fetched actually exists

func (*State) Login added in v1.1.0

func (state *State) Login(username string, w http.ResponseWriter)

Login generates a random session ID, throws that into the DB,

then sets that session ID into the cookie

func (*State) LoginPostHandler

func (state *State) LoginPostHandler(w http.ResponseWriter, r *http.Request)

LoginPostHandler only handles POST requests, verifying forms named "username" and "password" Comparing values with those in BoltDB, and if it passes, stores the verified username in the cookie Note: As opposed to the other Handlers above, now commented out, this one deals with the redirects, so worth handling in the library.

func (*State) LogoutHandler

func (state *State) LogoutHandler(w http.ResponseWriter, r *http.Request)

LogoutHandler clears the "user" cookie, logging the user out

func (*State) NewUserToken added in v1.0.2

func (state *State) NewUserToken(w http.ResponseWriter, r *http.Request)

NewUserToken is a convenient handler that generates and provides a new user registration token

func (*State) SetFlash

func (state *State) SetFlash(msg string, w http.ResponseWriter)

SetFlash sets a flash message inside a cookie, which, combined with the UserEnvMiddle

middleware, pushes the message into context and then template

func (*State) UserSignupPostHandler

func (state *State) UserSignupPostHandler(w http.ResponseWriter, r *http.Request)

UserSignupPostHandler only handles POST requests, using forms named "username", "password" Signing up users as necessary, inside the AuthConf

func (*State) UserSignupTokenPostHandler added in v1.1.0

func (state *State) UserSignupTokenPostHandler(w http.ResponseWriter, r *http.Request)

UserSignupTokenPostHandler only handles POST requests, using forms named "username", "password", and "register_key"

	This is an alternative to UserSignupPostHandler, adding registration token support
 That token is verified against the DB before registration

type User

type User struct {
	Name string
	Role string
}

User is what is stored inside the context

func (*User) GetName

func (u *User) GetName() string

GetName is a helper function that sets the user blank if User is nil This allows use in Templates and the like

func (*User) IsAdmin

func (u *User) IsAdmin() bool

IsAdmin checks if the given user is an admin

func (*User) IsValid added in v1.1.4

func (u *User) IsValid() bool

IsLoggedIn checks if the given User is valid

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

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