public function auth($nonce = null, $params = null)
    {
        $params = $params ?: array();

        $client_id = $this->params['client_id'];
        $client_key = $this->params['client_key'];

        // 1) Get nonce
        $nonce = $nonce ?: $this->server->request('auth');

        // 2) Create key hash
        $key_hash = md5("{$client_id}::{$client_key}");

        // 3) Create auth key
        $auth_key = md5("{$nonce}{$client_id}{$key_hash}");

        // 4) Authenticate with client params
        $params['client'] = $client_id;
        $params['key'] = $auth_key;

        if ($this->params['version']) {
            $params['$v'] = $this->params['version'];
        }
        if ($this->params['api']) {
            $params['$api'] = $this->params['api'];
        }
        if ($this->params['session']) {
            $params['$session'] = $this->params['session'];
        }
        if (isset($this->params['route']['client'])) {
            $params['$route'] = $this->params['route'];
        }
        if (isset($_SERVER['REMOTE_ADDR']) && $ip_address = $_SERVER['REMOTE_ADDR']) {
            $params['$ip'] = $ip_address;
        }
        if ($this->cache) {
            $params['$cached'] = $this->cache->get_versions();
        }

        $this->authed = true;
        
        try {
            return $this->server->request('auth', $params);
        } catch (NetworkException $e) {
            $this->request_rescue($e);
            return $this->auth();
        }
    }