"github.com/go-redis/redis/v8"
"github.com/oilastudio/oneaccount-go"
var redisClient = redis.NewClient(&redis.Options{})
// If engine setter and getter are not set an in-memory engine will be used.
// For production it is recommended to provide an engine setter and getter:
// for this example we will use redis but any other storage could be used
oneaccount.SetEngineSetter(func(ctx context.Context, k string, v []byte) error {
return redisClient.Set(ctx, k, v, 3 * time.Minute).Err()
oneaccount.SetEngineGetter(func(ctx context.Context, k string) ([]byte, error) {
v, err := redisClient.Get(ctx, k).Result()
return []byte(v), redisClient.Del(ctx, k).Err()
// The route URL is the callback URL you have set when you created One account app.
http.Handle("/oneaccountauth", oa.Auth(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// NOTE: never return code 200 if a user is not authenticated
if !oneaccount.IsAuthenticated(r) {
http.Error(w, "something went wrong while authenticating, please try again later", http.StatusInternalServerError)
// a user is authenticated and you can implement any logic your application
// needs. oneaccount.Data(r) returns the data sent by the user
// after successful authentication.
// since One account doesn't differentiate between sign up and sign in,
// you can use userId to check if the user signed up c on your website or not.
// the same way you can access any other data you requested from the user:
FirstName string `json:"firstName"`
UserID int `json:"userId"`
// the object contains all fields (camelCased) that are defined in the app (Requested data)
if err := json.Unmarshal(oneaccount.Data(r), &data); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
// any data returned here would be sent to oneaccount-authenticated event on front-end e.g.:
w.Header().Set("Content-Type", "application/json; charset=utf-8")
json.NewEncoder(w).Encode(data)
// NOTE: handle the error