Skip to main content

Introduction

WhiteBIT OAuth 2.0 implementation uses the standard Authorization Code Grant flow. This flow is suitable for server-side applications where the client secret can be securely stored.
package main

import (
	"bytes"
	"context"
	"crypto/rand"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
	"net/url"
	"time"
)

// TokenResponse represents the OAuth token response
type TokenResponse struct {
	Data struct {
		AccessToken  string `json:"access_token"`
		ExpiresIn    int    `json:"expires_in"`
		RefreshToken string `json:"refresh_token"`
		Scope        string `json:"scope"`
		TokenType    string `json:"token_type"`
	} `json:"data"`
}

const BASE_URL = "https://whitebit.com"
const CLIENT_ID = "YOUR_CLIENT_ID"
const CLIENT_SECRET = "YOUR_CLIENT_SECRET"

// Initiate OAuth flow
func initiateOAuthFlowHandler(w http.ResponseWriter, r *http.Request) {
	b := make([]byte, 32)
	rand.Read(b)
	state := base64.RawURLEncoding.EncodeToString(b)

	// In production, store state in session

	authURL, _ := url.Parse(BASE_URL + "/auth/login")
	q := authURL.Query()
	q.Set("clientId", CLIENT_ID)
	q.Set("state", state)
	authURL.RawQuery = q.Encode()

	http.Redirect(w, r, authURL.String(), http.StatusFound)
}

// Handle OAuth callback
func oauthCallbackHandler(w http.ResponseWriter, r *http.Request) {
	code := r.URL.Query().Get("code")
	state := r.URL.Query().Get("state")

	// Verify state here...

	token, err := exchangeCodeForToken(r.Context(), code)
	if err != nil {
		http.Error(w, "Authentication failed", http.StatusInternalServerError)
		return
	}

	fmt.Fprintf(w, "Token received: %s", token.Data.AccessToken)
}

func exchangeCodeForToken(ctx context.Context, code string) (*TokenResponse, error) {
	data := url.Values{}
	data.Set("client_id", CLIENT_ID)
	data.Set("client_secret", CLIENT_SECRET)
	data.Set("code", code)

	resp, err := http.PostForm(BASE_URL+"/oauth2/token", data)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	var tokenResponse TokenResponse
	json.NewDecoder(resp.Body).Decode(&tokenResponse)
	return &tokenResponse, nil
}

Scopes

Available Scopes (requested during client setup):
  • general: General API access
  • show.userinfo: Access to basic user information
  • users.read: Read user data
  • users.email.read: Read user email information
  • users.kyc.read: Information about whether a user has passed KYC verification
  • orders.read: Read trading orders
  • orders.create: Create trading orders
  • orders.delete: Delete trading orders
  • balances.read: Read account balances
  • markets.read: Read market information
  • deals.read: Read trading deals
  • orders_history.read: Read order history
  • users.transactions.read: Read user transactions
  • users.converts.read: Read currency conversion history
  • users.balances.read: Read user account balances
  • users.orders.read: Read user orders
  • users.deals.read: Read user deals