Skip to content

Custom confirm logic

Robert Brennan edited this page Oct 2, 2019 · 3 revisions

By default, if you enable the confirm package, Authboss won't let users log in at all until their email is confirmed. If you want to show a page that says something like a confirmation email has been sent to you@domain.com, you'll need to implement some custom logic. In the examples below, we've created that page at /check-confirmation.

  1. Don't use the confirm middleware
  2. Change your User implementation to always return true for GetConfirmed(), and create a GetActuallyConfirmed() function
  3. Implement your own confirm middleware. Something like:
// GetUserAuthMiddleware ensures a user is logged in
func GetUserAuthMiddleware(auth *authboss.Authboss) func(http.Handler) http.Handler {
    return func(next http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            user, err := auth.CurrentUser(r)
            if err != nil {
                handleNotAuthorized(w, r)
                return
            } else if !user.(*database.User).GetActuallyConfirmed() {
                http.Redirect(w, r, "/check-confirmation", 307)
                return
            }
            next.ServeHTTP(w, r)
        })
    }
}
  1. (optional) create middleware that requires a user to be registered, but not confirmed
// GetUserAuthUnconfirmedMiddleware allows users to access a page even if they have not confirmed their email
func GetUserAuthUnconfirmedMiddleware(auth *authboss.Authboss) func(http.Handler) http.Handler {
    return func(next http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            user, err := auth.CurrentUser(r)
            if err != nil {
                handleNotAuthorized(w, r)
                return
            }
            next.ServeHTTP(w, r)
        })
    }
}
  1. Register an event to log the user in after registration. Usually AB does this automatically, but not if the confirm module is enabled.
    ab.Events.After(authboss.EventRegister, func(w http.ResponseWriter, r *http.Request, handled bool) (bool, error) {
        // Authboss won't log the user in post-registration if the confirm package is enabled.
        // We do it manually here so we can display a helpful message with their email address.
        user, err := ab.CurrentUser(r)
        if err != nil {
            logrus.Errorf("Error while logging in user in after registration: %v", err)
            return handled, err
        }
        authboss.PutSession(w, authboss.SessionKey, user.GetPID())
        logrus.Infof("Manually logged user %s in after registration", user.GetPID())
        http.Redirect(w, r, "/check-confirmation", 307)
        return handled, nil
    })
  1. (optional) implement confirmation resend
 	confirmer := confirm.Confirm{Authboss: auth} 
	router.HandleFunc("/resend-confirmation", func(w http.ResponseWriter, r *http.Request) {
		user := serverutil.GetUser(r)
		confirmer.StartConfirmation(r.Context(), user, true)
                /* render HTML page saying an email has been sent */
	})
Clone this wiki locally