28 KiB
Use Cases
Get Current User
CurrentUser can be retrieved by calling Authboss.CurrentUser but a pre-requisite is that Authboss.LoadClientState has been called first to load the client state into the request context. This is typically achieved by using the Authboss.LoadClientStateMiddleware, but can be done manually as well.
Reset Password
Updating a user's password is non-trivial for several reasons:
- The bcrypt algorithm must have the correct cost, and also be being used.
- The user's remember me tokens should all be deleted so that previously authenticated sessions are invalid
- Optionally the user should be logged out (not taken care of by UpdatePassword)
In order to do this, we can use the Authboss.UpdatePassword method. This ensures the above facets are taken care of which the exception of the logging out part.
If it's also desirable to have the user logged out, please use the following methods to erase all known sessions and cookies from the user.
Note: DelKnownSession has been deprecated for security reasons
User Auth via Password
Info and Requirements | |
---|---|
Module | auth |
Pages | login |
Routes | /login |
Emails | None |
Middlewares | LoadClientStateMiddleware |
ClientStorage | Session and Cookie |
ServerStorer | ServerStorer |
User | AuthableUser |
Values | UserValuer |
Mailer | None |
To enable this side-effect import the auth module, and ensure that the requirements above are met. It's very likely that you'd also want to enable the logout module in addition to this.
Direct a user to GET /login
to have them enter their credentials and log in.
User Auth via OAuth1
Info and Requirements | |
---|---|
Module | oauth1 |
Pages | None |
Routes | /oauth1/{provider}, /oauth1/callback/{provider} |
Emails | None |
Middlewares | LoadClientStateMiddleware |
ClientStorage | Session |
ServerStorer | OAuth1ServerStorer |
User | OAuth1User |
Values | None |
Mailer | None |
This is a tougher implementation than most modules because there's a lot going on. In addition to the
requirements stated above, you must also configure the oauth1.Providers
. It's a public variable in the module.
import oauth1 "github.com/stephenafamo/authboss-oauth1"
oauth1.Providers = map[string]oauth1.Provider{}
The providers require an oauth1 configuration that's typical for the Go oauth1 package, but in addition
to that they need a FindUserDetails
method which has to take the token that's retrieved from the oauth1
provider, and call an endpoint that retrieves details about the user (at LEAST user's uid).
These parameters are returned in map[string]string
form and passed into the oauth1.ServerStorer
.
Please see the following documentation for more details:
User Auth via OAuth2
Info and Requirements | |
---|---|
Module | oauth2 |
Pages | None |
Routes | /oauth2/{provider}, /oauth2/callback/{provider} |
Emails | None |
Middlewares | LoadClientStateMiddleware |
ClientStorage | Session |
ServerStorer | OAuth2ServerStorer |
User | OAuth2User |
Values | None |
Mailer | None |
This is a tougher implementation than most modules because there's a lot going on. In addition to the
requirements stated above, you must also configure the OAuth2Providers
in the config struct.
The providers require an oauth2 configuration that's typical for the Go oauth2 package, but in addition
to that they need a FindUserDetails
method which has to take the token that's retrieved from the oauth2
provider, and call an endpoint that retrieves details about the user (at LEAST user's uid).
These parameters are returned in map[string]string
form and passed into the OAuth2ServerStorer
.
Please see the following documentation for more details:
User Registration
Info and Requirements | |
---|---|
Module | register |
Pages | register |
Routes | /register |
Emails | None |
Middlewares | LoadClientStateMiddleware |
ClientStorage | Session |
ServerStorer | CreatingServerStorer |
User | AuthableUser, optionally ArbitraryUser |
Values | UserValuer, optionally also ArbitraryValuer |
Mailer | None |
Users can self-register for a service using this module. You may optionally want them to confirm themselves, which can be done using the confirm module.
The complicated part in implementing registrations are around the RegisterPreserveFields
. This is to
help in the case where a user fills out many fields, and then say enters a password
which doesn't meet minimum requirements and it fails during validation. These preserve fields should
stop the user from having to type in all that data again (it's a whitelist). This must be used
in conjuction with ArbitraryValuer
and although it's not a hard requirement ArbitraryUser
should be used otherwise the arbitrary values cannot be stored in the database.
When the register module sees arbitrary data from an ArbitraryValuer
, it sets the data key
authboss.DataPreserve
with a map[string]string
in the data for when registration fails.
This means the (whitelisted) values entered by the user previously will be accessible in the
templates by using .preserve.field_name
. Preserve may be empty or nil so use
{{with ...}}
to make sure you don't have template errors.
There is additional Godoc documentation on the RegisterPreserveFields
config option as well as
the ArbitraryUser
and ArbitraryValuer
interfaces themselves.
Confirming Registrations
Info and Requirements | |
---|---|
Module | confirm |
Pages | confirm |
Routes | /confirm |
Emails | confirm_html, confirm_txt |
Middlewares | LoadClientStateMiddleware, confirm.Middleware |
ClientStorage | Session |
ServerStorer | ConfirmingServerStorer |
User | ConfirmableUser |
Values | ConfirmValuer |
Mailer | Required |
Confirming registrations via e-mail can be done with this module (whether or not done via the register module).
A hook on register kicks off the start of a confirmation which sends an e-mail with a token for the user.
When the user re-visits the page, the BodyReader
must read the token and return a type that returns
the token.
Confirmations carry two values in the database to prevent a timing attack. The selector and the verifier, always make sure in the ConfirmingServerStorer you're searching by the selector and not the verifier.
Password Recovery
Info and Requirements | |
---|---|
Module | recover |
Pages | recover_start, recover_middle (not used for renders, only values), recover_end |
Routes | /recover, /recover/end |
Emails | recover_html, recover_txt |
Middlewares | LoadClientStateMiddleware |
ClientStorage | Session |
ServerStorer | RecoveringServerStorer |
User | RecoverableUser |
Values | RecoverStartValuer, RecoverMiddleValuer, RecoverEndValuer |
Mailer | Required |
The flow for password recovery is that the user is initially shown a page that wants their PID
to
be entered. The RecoverStartValuer
retrieves that on POST
to /recover
.
An e-mail is sent out, and the user clicks the link inside it and is taken back to /recover/end
as a GET
, at this point the RecoverMiddleValuer
grabs the token and will insert it into the data
to be rendered.
They enter their password into the form, and POST
to /recover/end
which sends the token and
the new password which is retrieved by RecoverEndValuer
which sets their password and saves them.
Password recovery has two values in the database to prevent a timing attack. The selector and the verifier, always make sure in the RecoveringServerStorer you're searching by the selector and not the verifier.
Remember Me
Info and Requirements | |
---|---|
Module | remember |
Pages | None |
Routes | None |
Emails | None |
Middlewares | LoadClientStateMiddleware, |
Middlewares | LoadClientStateMiddleware, remember.Middleware |
ClientStorage | Session, Cookies |
ServerStorer | RememberingServerStorer |
User | User |
Values | RememberValuer (not a Validator) |
Mailer | None |
Remember uses cookie storage to log in users without a session via the remember.Middleware
.
Because of this this middleware should be used high up in the stack, but it also needs to be after
the LoadClientStateMiddleware
so that client state is available via the authboss mechanisms.
There is an intricacy to the RememberingServerStorer
, it doesn't use the User
struct at all,
instead it simply instructs the storer to save tokens to a pid and recall them just the same. Typically
in most databases this will require a separate table, though you could implement using pg arrays
or something as well.
A user who is logged in via Remember tokens is also considered "half-authed" which is a session
key (authboss.SessionHalfAuthKey
) that you can query to check to see if a user should have
full rights to more sensitive data, if they are half-authed and they want to change their user
details for example you may want to force them to go to the login screen and put in their
password to get a full auth first. The authboss.Middleware
has a boolean flag to forceFullAuth
which prevents half-authed users from using that route.
Locking Users
Info and Requirements | |
---|---|
Module | lock |
Pages | None |
Routes | None |
Emails | None |
Middlewares | LoadClientStateMiddleware, lock.Middleware |
ClientStorage | Session |
ServerStorer | ServerStorer |
User | LockableUser |
Values | None |
Mailer | None |
Lock ensures that a user's account becomes locked if authentication (both auth, oauth2, otp) are failed enough times.
The middleware protects resources from locked users, without it, there is no point to this module. You should put in front of any resource that requires a login to function.
Expiring User Sessions
Info and Requirements | |
---|---|
Module | expire |
Pages | None |
Routes | None |
Emails | None |
Middlewares | LoadClientStateMiddleware, expire.Middleware |
ClientStorage | Session |
ServerStorer | None |
User | User |
Values | None |
Mailer | None |
Note: Unlike most modules in Authboss you must call expire.Setup()
to enable this module. See the sample to see how to do this. This may be changed in the future.
Expire simply uses sessions to track when the last action of a user is, if that action is longer than configured then the session is deleted and the user removed from the request context.
This middleware should be inserted at a high level (closer to the request) in the middleware chain to ensure that "activity" is logged properly, as well as any middlewares down the chain do not attempt to do anything with the user before it's removed from the request context.
One Time Passwords
Info and Requirements | |
---|---|
Module | otp |
Pages | otp, otpadd, otpclear |
Routes | /otp/login, /otp/add, /otp/clear |
Emails | None |
Middlewares | LoadClientStateMiddleware |
ClientStorage | Session and Cookie |
ServerStorer | ServerStorer |
User | otp.User |
Values | UserValuer |
Mailer | None |
One time passwords can be useful if users require a backup password in case they lose theirs, or they're logging in on an untrusted computer. This module allows users to add one time passwords, clear them, or log in with them.
Logging in with a one time password instead of a password is identical to having logged in normally with their typical password with the exception that the one time passwords are consumed immediately upon use and cannot be used again.
otp
should not be confused with two factor authentication. Although 2fa also uses one-time passwords
the otp
module has nothing to do with it and is strictly a mechanism for logging in with an alternative
to a user's regular password.
Two Factor Authentication
2FA in Authboss is implemented in a few separate modules: twofactor, totp2fa and sms2fa.
You should use two factor authentication in your application if you want additional security beyond that of just simple passwords. Each 2fa module supports a different mechanism for verifying a second factor of authentication from a user.
Two-Factor Recovery
Info and Requirements | |
---|---|
Module | twofactor |
Pages | recovery2fa |
Routes | /2fa/recovery/regen |
Emails | None |
Middlewares | LoadClientStateMiddleware |
ClientStorage | Session |
ServerStorer | ServerStorer |
User | twofactor.User |
Values | None |
Mailer | None |
Note: Unlike most modules in Authboss you must construct a twofactor.Recovery
and call .Setup()
on it to enable this module. See the sample to see how to do this. This may be changed in the future.
Package twofactor is all about the common functionality of providing backup codes for two factor mechanisms. Instead of each module implementing backup codes on it's own, common functionality has been put here including a route to regenerate backup codes.
Backup codes are useful in case people lose access to their second factor for authentication. This happens when users lose their phones for example. When this occurs, they can use one of their backup-codes.
Backup codes are one-time use, they are bcrypted for security, and they only allow bypassing the 2fa
authentication part, they cannot be used in lieu of a user's password, for that sort of recovery see
the otp
module.
Two-Factor Setup E-mail Authorization
Info and Requirements | |
---|---|
Module | twofactor |
Pages | twofactor_verify |
Routes | /2fa/recovery/regen |
Emails | twofactor_verify_email_html, twofactor_verify_email_txt |
Middlewares | LoadClientStateMiddleware |
ClientStorage | Session |
ServerStorer | ServerStorer |
User | twofactor.User |
Values | twofactor.EmailVerifyTokenValuer |
Mailer | Required |
To enable this feature simply turn on
authboss.Config.Modules.TwoFactorEmailAuthRequired
and new routes and
middlewares will be installed when you set up one of the 2fa modules.
When enabled, the routes for setting up 2fa on an account are protected by a
middleware that will redirect to /2fa/{totp,sms}/email/verify
where
Page twofactor_verify
is displayed. The user is prompted to authorize the
addition of 2fa to their account. The data for this page contains email
and
a url
for the POST. The url is required because this page is shared between
all 2fa types.
Once they POST to the url, a token is stored in their session and an e-mail is
sent with that token. When they click the link that goes to
/2fa/{totp,sms}/email/verify/end
with a token in the query string the session
token is verified and exchanged for a value that says they're verified and
lastly it redirects them to the setup URL for the type of 2fa they were
attempting to setup.
Time-Based One Time Passwords 2FA (totp)
Info and Requirements | |
---|---|
Module | totp2fa |
Pages | totp2fa_{setup,confirm,remove,validate}, totp2fa_{confirm,remove}_success |
Routes | /2fa/totp/{setup,confirm,qr,remove,validate} |
Emails | None |
Middlewares | LoadClientStateMiddleware |
ClientStorage | Session (SECURE!) |
ServerStorer | ServerStorer |
User | totp2fa.User |
Values | TOTPCodeValuer |
Mailer | None |
Note: Unlike most modules in Authboss you must construct a totp2fa.TOTP
and call .Setup()
on it to enable this module. See the sample to see how to do this This may be changed in the future.
Note: To allow users to regenerate their backup codes, you must also use the twofactor
module.
Note: Routes are protected by authboss.Middleware
so only logged in users can access them.
You can configure whether unauthenticated users should be redirected to log in or are 404'd using
the authboss.Config.Modules.RoutesRedirectOnUnathed
configuration flag.
Adding 2fa to a user
When a logged in user would like to add 2fa to their account direct them GET /2fa/totp/setup
, the GET
on this page does virtually nothing so you don't have to use it, just POST
immediately to have
a smoother flow for the user. This puts the 2fa secret in their session temporarily meaning you must
have proper secure sessions for this to be secure.
They will be redirected to GET /2fa/totp/confirm
where the data will show totp2fa.DataTOTPSecret
,
this is the key that user's should enter into their Google Authenticator or similar app. Once they've
added it they need to send a POST /2fa/totp/confirm
with a correct code which removes the 2fa secret
from their session and permanently adds it to their totp2fa.User
and 2fa is now enabled for them.
The data from the POST
will contain a key twofactor.DataRecoveryCodes
that contains an array
of recovery codes for the user.
If you wish to show the user a QR code, GET /2fa/totp/qr
at any time during or after totp2fa setup
will return a 200x200 png QR code that they can scan.
Removing 2fa from a user
A user begins by going to GET /2fa/totp/remove
and enters a code which posts to POST /2fa/totp/remove
and if it's correct they're shown a success page and 2fa is removed from them, if not they get
validation errors.
Logging in with 2fa
When a user goes to log in, the totp
module checks the user after they log in for the presence of
a totp2fa secret, if there is one it does not give them a logged in session value immediately and
redirects them to GET /2fa/totp/validate
where they must enter a correct code to POST /2fa/totp/validate
if the code is correct they're logged in normally as well as they get the session value
authboss.Session2FA
set to "totp"
to prove that they've authenticated with two factors.
Using Recovery Codes
Both when logging in and removing totp2fa from an account, a recovery code may be used instead. They can
POST
to the same url, they simply send a different form field. The recovery code is consumed on use
and may not be used again.
Text Message 2FA (sms)
Package sms2fa uses sms shared secrets as a means to authenticate a user with a second factor: their phone number.
Info and Requirements | |
---|---|
Module | sms2fa |
Pages | sms2fa_{setup,confirm,remove,validate}, sms2fa_{confirm,remove}_success |
Routes | /2fa/{setup,confirm,remove,validate} |
Emails | None |
Middlewares | LoadClientStateMiddleware |
ClientStorage | Session (SECURE!) |
ServerStorer | ServerStorer |
User | sms2fa.User, sms2fa.SMSNumberProvider |
Values | SMSValuer, SMSPhoneNumberValuer |
Mailer | None |
Note: Unlike most modules in Authboss you must construct a sms2fa.SMS
and call .Setup()
on it to enable this module. See the sample to see how to do this. This may be changed in the future.
Note: To allow users to regenerate their backup codes, you must also use the twofactor
module.
Note: Routes are protected by authboss.Middleware
so only logged in users can access them.
You can configure whether unauthenticated users should be redirected to log in or are 404'd using
the authboss.Config.Modules.RoutesRedirectOnUnathed
configuration flag.
Note: sms2fa always stores the code it's expecting in the user's session therefore you must have secure sessions or the code itself is not secure!
Note: sms2fa pages all send codes via sms on POST
when no data code is given. This is also how
users can resend the code in case they did not get it (for example a second
POST /2fa/sms/{confirm,remove}
with no form-fields filled in will end up resending the code).
Note: Sending sms codes is rate-limited to 1 sms/10 sec for that user, this is controlled by placing a timestamp in their session to prevent abuse.
Adding 2fa to a user
When a logged in user would like to add 2fa to their account direct them GET /2fa/sms/setup
where
they must enter a phone number. If the logged in user also implements sms2fa.SMSNumberProvider
then
this interface will be used to retrieve a phone number (if it exists) from the user and put it in
sms2fa.DataSMSPhoneNumber
so that the user interface can populate it for the user, making it convenient
to re-use an already saved phone number inside the user.
Once they POST /2fa/sms/setup
with a phone number, the sms2fa.Sender
interface will be
invoked to send the SMS code to the user and they will be redirected to GET /2fa/sms/confirm
where
they enter the code they received which does a POST /2fa/sms/confirm
to store the phone number
they were confirming permanently on their user using sms2fa.User
which enables sms2fa for them.
The data from the POST
will contain a key twofactor.DataRecoveryCodes
that contains an array
of recovery codes for the user.
Removing 2fa from a user
A user begins by going to GET /2fa/sms/remove
. This page does nothing on it's own. In order to
begin the process POST /2fa/sms/remove
with no data (or a recovery code to skip needing the sms code)
to send the sms code to the user. Then they can POST /2fa/sms/remove
again with the correct code
to have it permanently removed.
Logging in with 2fa
When a user goes to log in, the sms
module checks the user after they log in for the presence of
a sms2fa phone number, if there is one it does not give them a logged in session value but instead
sends an SMS code to their configured number and and redirects them to GET /2fa/sms/validate
where they must enter a correct code to POST /2fa/totp/validate
. If the code is correct they're
logged in normally as well as they get the session value authboss.Session2FA
set to "sms"
to prove
that they've authenticated with two factors.
Using Recovery Codes
Same as totp2fa above.