diff --git a/sync.go b/sync.go
index 1e27496fd0dd170b87261811709ca0146eceb506..f09bfaf17568d29d9cbaf8843babd12201276565 100644
--- a/sync.go
+++ b/sync.go
@@ -8,8 +8,10 @@ import (
 	"log"
 	"mime/multipart"
 	"net/http"
+	"net/url"
 	"os"
 	"path/filepath"
+	"strings"
 	"sync"
 	"time"
 )
@@ -27,11 +29,32 @@ type SyncClient interface {
 type remoteServer struct {
 	client    *http.Client
 	remoteURL string
+	username  string
+	password  string
+}
+
+func extractAuth(uri string) (string, string, string) {
+	parsed, err := url.Parse(uri)
+	if err != nil {
+		return uri, "", ""
+	}
+	if strings.Contains("@", parsed.Host) {
+		hostParts := strings.SplitN(parsed.Host, "@", 2)
+		parsed.Host = hostParts[1]
+		authParts := strings.SplitN(hostParts[0], ":", 2)
+		if len(authParts) == 2 {
+			return parsed.String(), authParts[0], authParts[1]
+		}
+	}
+	return uri, "", ""
 }
 
 func NewRemoteServer(remoteURL string) *remoteServer {
+	remoteURL, username, password := extractAuth(remoteURL)
 	return &remoteServer{
 		remoteURL: remoteURL,
+		username:  username,
+		password:  password,
 		client:    &http.Client{},
 	}
 }
@@ -48,6 +71,9 @@ func (r *remoteServer) DiffRequest(diffreq *diffRequest) (*diffResponse, error)
 		return nil, err
 	}
 	req.Header.Set("Content-Type", "application/json")
+	if r.username != "" {
+		req.SetBasicAuth(r.username, r.password)
+	}
 	resp, err := r.client.Do(req)
 	if err != nil {
 		return nil, err
@@ -120,7 +146,10 @@ func (r *remoteServer) SendBook(book *Book, files []*File) error {
 	if err != nil {
 		return err
 	}
-	req.Header.Add("Content-Type", w.FormDataContentType())
+	req.Header.Set("Content-Type", w.FormDataContentType())
+	if r.username != "" {
+		req.SetBasicAuth(r.username, r.password)
+	}
 
 	resp, err := r.client.Do(req)
 	if err != nil {