func (helios Helios) CallbackHandler(w http.ResponseWriter, r *http.Request) {
	log.Debug("Handling callback request")
	encodedState := r.URL.Query().Get("state")
	state, err := base64.StdEncoding.DecodeString(encodedState)
	if err != nil {
		log.Error(err)
		w.WriteHeader(http.StatusInternalServerError)
		return
	}
	profile, err := helios.provider.FetchUser(r)
	if err != nil {
		log.Error(err)
		w.WriteHeader(http.StatusInternalServerError)
		return
	}
	log.Debugf("Authorized. Redirecting to %s", string(state))
	exp := time.Now().Add(helios.jwtConfig.Expiration)
	jwt, err := IssueJWTWithSecret(helios.jwtConfig.Secret, profile.Email, exp)
	if err != nil {
		log.Error(err)
	}
	http.SetCookie(w, &http.Cookie{
		Name:     CookieName,
		Value:    jwt,
		Expires:  exp,
		Path:     "/",
		Secure:   true,
		HttpOnly: true,
	})
	http.Redirect(w, r, string(state), http.StatusFound)
}
CallbackHandler handles OAuth2 callback flow
package authentication
import (
	"encoding/base64"
	"errors"
	"net/http"
	"time"
	"github.com/cyakimov/helios/authentication/providers"
	log "github.com/sirupsen/logrus"
)
const CookieName = "Helios_Authorization"
const HeaderName = "Helios-Jwt-Assertion"
var ErrUnauthorized = errors.New("unauthorized request")
type JWTConfig struct {
	Secret     string
	Expiration time.Duration
}
type Helios struct {
	provider  providers.OAuth2Provider
	jwtConfig JWTConfig
}
func NewHeliosAuthentication(provider providers.OAuth2Provider, jwtSecret string, jwtExpiration time.Duration) Helios {
	return Helios{
		provider: provider,
		jwtConfig: JWTConfig{
			Secret:     jwtSecret,
			Expiration: jwtExpiration,
		},
	}
}
func (helios Helios) Middleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		log.Debugf("Authenticating request %q", r.URL)
		if err := authenticate(helios.jwtConfig.Secret, r); err != nil {
			log.Debugf("Authentication failed for %q", r.URL)
			scheme := "http"
			if r.TLS != nil {
				scheme = "https"
			}
			callback := scheme + "://" + r.Host + "/.well-known/callback"
			url := helios.provider.GetLoginURL(callback, r.RequestURI)
			log.Debugf("Redirecting to %s", url)
			http.Redirect(w, r, url, http.StatusTemporaryRedirect)
			return
		}
		next.ServeHTTP(w, r)
	})
}