Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BTCChina always returns 401 #191

Closed
langfors opened this issue Oct 29, 2013 · 21 comments
Closed

BTCChina always returns 401 #191

langfors opened this issue Oct 29, 2013 · 21 comments

Comments

@langfors
Copy link

Hello,

Firstly, thanks for an incredible library! Love it!

I am having trouble using the new BTCChina support. I always get a 401; even when using the BTCChinaTradeDemo example. Any advice or help appreciated. Here is the trace output:

Oct 29, 2013 10:27:26 AM com.xeiam.xchange.ExchangeFactory createExchange
FINE: Creating exchange from specification
Oct 29, 2013 10:27:26 AM si.mazi.rescu.Config <clinit>
FINE: Configuration from rescu.properties:
Oct 29, 2013 10:27:26 AM si.mazi.rescu.Config <clinit>
FINE: httpReadTimeout = 30000
Oct 29, 2013 10:27:26 AM si.mazi.rescu.Config <clinit>
FINE: proxyHost = null
Oct 29, 2013 10:27:26 AM si.mazi.rescu.Config <clinit>
FINE: proxyPort = null
Oct 29, 2013 10:27:27 AM si.mazi.rescu.HttpTemplate executeRequest
FINE: Executing POST request at https://btcchina.com/api_trade_v1.php
Oct 29, 2013 10:27:27 AM si.mazi.rescu.HttpTemplate executeRequest
FINEST: Request body = {"id":1,"method":"getOrders","params":[]}
Oct 29, 2013 10:27:27 AM si.mazi.rescu.HttpTemplate executeRequest
FINEST: Request headers = {Authorization=Basic OWRmYTY1ZWUtZTAyMy00OGZiLWE4YzEtY2JhNmVhNGIwMWZmOjQyMzA4MzBjZTViMDU1ZDM5YTdhNWFiM2Q2MmY5OGFmNThlMzdjMmQ=, Json-Rpc-Tonce=1383056847195000}
Oct 29, 2013 10:27:27 AM si.mazi.rescu.HttpTemplate configureURLConnection
FINEST: Header request property: key='Authorization', value='Basic OWRmYTY1ZWUtZTAyMy00OGZiLWE4YzEtY2JhNmVhNGIwMWZmOjQyMzA4MzBjZTViMDU1ZDM5YTdhNWFiM2Q2MmY5OGFmNThlMzdjMmQ='
Oct 29, 2013 10:27:27 AM si.mazi.rescu.HttpTemplate configureURLConnection
FINEST: Header request property: key='Accept-Charset', value='UTF-8'
Oct 29, 2013 10:27:27 AM si.mazi.rescu.HttpTemplate configureURLConnection
FINEST: Header request property: key='Json-Rpc-Tonce', value='1383056847195000'
Oct 29, 2013 10:27:27 AM si.mazi.rescu.HttpTemplate configureURLConnection
FINEST: Header request property: key='User-Agent', value='ResCU JDK/6 AppleWebKit/535.7 Chrome/16.0.912.36 Safari/535.7'
Oct 29, 2013 10:27:27 AM si.mazi.rescu.HttpTemplate configureURLConnection
FINEST: Header request property: key='Content-Type', value='application/json'
Oct 29, 2013 10:27:27 AM si.mazi.rescu.HttpTemplate configureURLConnection
FINEST: Header request property: key='Accept', value='application/json'
Oct 29, 2013 10:27:28 AM sun.net.www.protocol.http.HttpURLConnection writeRequests
FINE: sun.net.www.MessageHeader@4bd38cb310 pairs: {POST /api_trade_v1.php HTTP/1.1: null}{Authorization: Basic OWRmYTY1ZWUtZTAyMy00OGZiLWE4YzEtY2JhNmVhNGIwMWZmOjQyMzA4MzBjZTViMDU1ZDM5YTdhNWFiM2Q2MmY5OGFmNThlMzdjMmQ=}{Accept-Charset: UTF-8}{Json-Rpc-Tonce: 1383056847195000}{User-Agent: ResCU JDK/6 AppleWebKit/535.7 Chrome/16.0.912.36 Safari/535.7}{Content-Type: application/json}{Accept: application/json}{Host: btcchina.com}{Connection: keep-alive}{Content-Length: 41}
Oct 29, 2013 10:27:28 AM sun.net.www.protocol.http.HttpURLConnection getInputStream
FINE: sun.net.www.MessageHeader@2dba62a94 pairs: {null: HTTP/1.1 301 Moved Permanently}{Location: https://www.btcchina.com/api_trade_v1.php}{Content-Length: 0}{Connection: close}
Oct 29, 2013 10:27:28 AM sun.net.www.protocol.http.HttpURLConnection followRedirect
FINE: Redirected from https://btcchina.com/api_trade_v1.php to https://www.btcchina.com/api_trade_v1.php
Oct 29, 2013 10:27:28 AM sun.net.www.protocol.http.HttpURLConnection writeRequests
FINE: sun.net.www.MessageHeader@3b5ff43e5 pairs: {GET /api_trade_v1.php HTTP/1.1: null}{User-Agent: Java/1.7.0_40}{Host: www.btcchina.com}{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}{Connection: keep-alive}
Oct 29, 2013 10:27:29 AM sun.net.www.http.HttpClient logFinest
FINEST: KeepAlive stream used: https://www.btcchina.com/api_trade_v1.php
Oct 29, 2013 10:27:29 AM sun.net.www.protocol.http.HttpURLConnection getInputStream
FINE: sun.net.www.MessageHeader@67385a8111 pairs: {null: HTTP/1.1 302 Moved Temporarily}{Server: nginx/1.2.9}{Date: Tue, 29 Oct 2013 14:27:29 GMT}{Content-Type: text/html}{Content-Length: 160}{Connection: keep-alive}{Location: https://vip.btcchina.com/api_trade_v1.php}{Set-Cookie: incap_ses_144_88065=1KPPP/ZVB1JtL0QM66n/AdHFb1IAAAAA/RkHXYfpKci3FMbW9ka80A==; path=/; Domain=.btcchina.com}{Set-Cookie: visid_incap_88065=8VH6RJUgTuur4cEGNrzyVdHFb1IAAAAAQUIPAAAAAABR8ueJs/2qYndR5324ZEwp; expires=Wed, 28 Oct 2015 16:06:13 GMT; path=/; Domain=.btcchina.com}{X-Iinfo: 8-24725040-24725042 NNNY CT(222 197 0) RT(1383056848394 74) q(0 0 4 -1) r(4 6)}{X-CDN: Incapsula}
Oct 29, 2013 10:27:29 AM sun.net.www.protocol.http.HttpURLConnection followRedirect
FINE: Redirected from https://www.btcchina.com/api_trade_v1.php to https://vip.btcchina.com/api_trade_v1.php
Oct 29, 2013 10:27:30 AM sun.net.www.protocol.http.HttpURLConnection writeRequests
FINE: sun.net.www.MessageHeader@3b5ff43e5 pairs: {GET /api_trade_v1.php HTTP/1.1: null}{User-Agent: Java/1.7.0_40}{Host: vip.btcchina.com}{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}{Connection: keep-alive}
Oct 29, 2013 10:27:30 AM sun.net.www.protocol.http.HttpURLConnection getInputStream
FINE: sun.net.www.MessageHeader@281edacc17 pairs: {null: HTTP/1.1 401 Unauthorized}{Server: nginx/1.2.9}{Date: Tue, 29 Oct 2013 14:27:30 GMT}{Content-Type: text/html; charset=UTF-8}{Connection: keep-alive}{X-Powered-By: PHP/5.4.17}{Set-Cookie: PHPSESSID=docsi4unv644gkhbtpensna9o7; path=/}{Expires: Thu, 19 Nov 1981 08:52:00 GMT}{Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0}{Pragma: no-cache}{WWW-Authenticate: Basic realm="Auth"}{Vary: User-Agent}{Set-Cookie: incap_ses_32_88065=H9/oL79lnDgZt9b/T7BxANLFb1IAAAAA/bJkE135ThhB8hHY8yNzdA==; path=/; Domain=.btcchina.com}{Set-Cookie: visid_incap_88065=nbsp1fPDSYiXTMnazbHmeNLFb1IAAAAAQUIPAAAAAABo/TRJ80es1xm+upOyvISn; expires=Thu, 29 Oct 2015 10:54:46 GMT; path=/; Domain=.btcchina.com}{X-Iinfo: 2-1530828-1515248 PNNN RT(1383056849829 235) q(0 0 0 -1) r(2 2)}{X-CDN: Incapsula}{Transfer-Encoding: chunked}
Oct 29, 2013 10:27:30 AM sun.net.www.protocol.http.HttpURLConnection$1 run
FINEST: Requesting Authentication: host =vip.btcchina.com url = https://vip.btcchina.com/api_trade_v1.php
Oct 29, 2013 10:27:30 AM sun.net.www.protocol.http.HttpURLConnection$1 run
FINEST: Authentication returned: null
Oct 29, 2013 10:27:30 AM sun.net.www.protocol.http.HttpURLConnection getServerAuthentication
FINER: Server Authentication for AuthenticationHeader: prefer Basic realm="Auth" returned null
Oct 29, 2013 10:27:30 AM si.mazi.rescu.HttpTemplate executeRequest
FINE: Request http status = 401
Oct 29, 2013 10:27:30 AM si.mazi.rescu.HttpTemplate executeRequest
FINEST: Http call returned 401; response body:
401 Unauthorized
Exception in thread "main" java.lang.reflect.UndeclaredThrowableException
    at com.sun.proxy.$Proxy6.getOrders(Unknown Source)
    at com.xeiam.xchange.btcchina.service.polling.BTCChinaPollingTradeService.getOpenOrders(BTCChinaPollingTradeService.java:69)
    at com.pg62.robarb.BTCChinaTradeDemo.printOpenOrders(BTCChinaTradeDemo.java:78)
    at com.pg62.robarb.BTCChinaTradeDemo.main(BTCChinaTradeDemo.java:41)
Caused by: java.io.IOException: HTTP status code was 401; response body: 401 Unauthorized
    at si.mazi.rescu.HttpTemplate.executeRequest(HttpTemplate.java:125)
    at si.mazi.rescu.RestInvocationHandler.invokeHttp(RestInvocationHandler.java:65)
    at si.mazi.rescu.RestInvocationHandler.invoke(RestInvocationHandler.java:51)
    ... 4 more
@timmolter
Copy link
Member

It could be that either the service is temporarily down or BTC-China changed their API unannounced. They had really bad docs to begin with and in fact I've never personally seen any docs. I'll log into their site and see if I can find anything.

@timmolter
Copy link
Member

Nope. I cannot get access to the API docs because I don't have two-factor auth enabled. If you have access and can post the docs here, then I can take a look. See screeny.
screen shot 2013-10-29 at 7 06 20 pm

@langfors
Copy link
Author

This should be the full doco; let me know if I can do anything else. Thanks again for looking at this! Cheers.

btcchina-api-docs
btcchina-api-docs-2
btcchina-api-docs-3
btcchina-api-docs-4
btcchina-api-docs-5
btcchina-api-docs-6
btcchina-api-docs-7
btcchina-api-docs-8
btcchina-api-docs-9
btcchina-api-docs-10
btcchina-api-docs-11
btcchina-api-docs-12
btcchina-api-docs-13

@timmolter
Copy link
Member

Thanks. I saw this url on your attachment: http://btcchina.org/api-trade-documentation-en

@timmolter
Copy link
Member

I'm getting a Exception in thread "main" javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No X509TrustManager implementation available whenever I run any BTCChina demo class. That's strange since the cert is a GoDaddy one. You'd think it would be default in the JVM.

Given that and my lack of free time ATM, I don't have time to look into your issue. I apologize for that.

I'd be happy to accept a PR and answer any questions if you have them.

@alexreijs
Copy link

Has anyone been able to verify / solve this problem? I seem to be having the same issue. I'm developing for iOS and have verified that my auth is correct (by checking hash / tonce / poststring etc with demo code which works) but still i keep getting "401 Unauthorized" errors. Please help :)

@mmazi
Copy link
Contributor

mmazi commented Nov 11, 2013

I did have some problems accessing BTCChina a few weeks back; after I changed the url to https://vip.btcchina.com, it was OK:

        Exchange exc = ExchangeFactory.INSTANCE.createExchange(BTCChinaExchange.class.getCanonicalName());
        final ExchangeSpecification spec = exc.getExchangeSpecification();
        spec.setSslUri("https://vip.btcchina.com");
        exc.applySpecification(spec);

BTW @timmolter , I think the current way to override default exchange settings could be improved to make it less error-prone and more user-friendly. I don't have time to do anything about it right now though.

@alexreijs
Copy link

Thanks for your reply mmazi! Unfortunately it did not help me since i'm still getting 401s. I know this has nothing to do with XChange since this is iOS code, but i've been stuck on this for two weeks and getting frustrated. That being said XChange is an awesome library, i often check to see the newest APIs :)

Hopefully someone can spot an error in my approach below:
Thanks again for any help!

(i have checked the tonce, access key and Basic Auth header with demo code that works, they are OK)

postFields: (
    "tonce=1384187641746740",
    "accesskey=22ad7998-f149-44b9-a5d2-e90c9b13757f",
    "requestmethod=post",
    "id=1",
    "method=getAccountInfo",
    "params="
)
headers: {
    Authorization = "Basic MjJhZDc5OTgtZjE0OS00NGI5LWE1ZDItZTkwYzliMTM3NTdmOjE4ZmYzZDllNjM2YjQ0OWYwMGM2MjQwOWYwYjFmYTVmM2YyZmYyOTI=";
    "Json-Rpc-Tonce" = 1384187641746740;
}
resultstring: 401 Unauthorized

@timmolter
Copy link
Member

I recently added the vip subdomain, and pushed the change. Regarding the 401 error, I cannot give any feedback on that as I haven't tried to use any of the authenticated API calls to BTC-China. I have been successful at using the market data API calls though. Of course, there is no authorization required for that, so it's a different ball game.

All I can recommend is that you either contact BTCChina for help or try to contact the original author who wrote our BTC-China code, and see if he knows how to get it to work.

@mmazi When you have some time, let me know what your idea is, and I'll implement it. Thanks as always!

@devinbethel
Copy link

I was able to work around this by using the python example given in the API docs.

The server seems to accept this format:
result = bc.buy("500.0","0.001")

*Let me clarify my results: I get the error message for no apparent when calling sellOrder and buyOrder using the PHP example but both work correctly when using the Python example.

@langfors
Copy link
Author

For what its worth; the BTCCPollingAccountService.getAccountInfo() calls;
which is an authenticated call, works just fine.

On Tue, Nov 12, 2013 at 7:37 AM, devinbethel notifications@github.comwrote:

I was able to work around this by using the python example given in the
API docs.


Reply to this email directly or view it on GitHubhttps://github.com//issues/191#issuecomment-28289791
.

@cherylnatsu
Copy link

Is the python example provided by official works? I doubt. It takes me long time to test, and I make all the efforts to make
the request the same as the php one, but php one works, python one didn't.

@foolooo
Copy link

foolooo commented Nov 14, 2013

Hi all,
I had the similar issue. I was using the official PHP code to get the account info which works fine. But when I try to change the code to either sellOrder or buyOrder I got 401 error. For the code I changed the value of the var_dump function to 'buyOrder', array(2630, 0.1) . I also changed http_build_query() and json_code() function

'params' => array("price" => $params[0],"amount" => $params[1],),

Im not sure if this is the right way of assigning the values for 'params'. Is there any other place I should have changed? .

Thank you for any suggestion.

Cheers

@davidalbela
Copy link

Did you try adding params to signature function?. The example code in PHP has comment the $params var.

@mkraemer
Copy link

The problem is that http_build_query substitutes the comma which delimits the items in the method parameter..

Check https://gist.github.com/mkraemer/7483878#file-btcchina-api for a working example :)

@foolooo
Copy link

foolooo commented Nov 16, 2013

@3lm4dn0 @mkraemer Thank you for your kind reply and the example. I really would like to have my code work if possible (it's easier for me to understand and modify). So now I changed the code as following and left the rest the same as the demo.

  $signature = http_build_query(array(
        'tonce' => $ts,
        'accesskey' => $accessKey,
        'requestmethod' => 'post',
        'id' => 1,
        'method' => $method,
        'params' => implode(',', $params),
          ));

in try()

  try { 
        var_dump(request('buyOrder', [2700,0.1]));

    } catch (Exception $e) {                
            echo "Error:".$e->getMessage();         
    } 

But it still does not work :(.

Any suggestion?

Thank you so much.

Cheers.

@foolooo
Copy link

foolooo commented Nov 16, 2013

@mkraemer Update. I replaced the http_build_query with your sprintf function and it works now! :D
Thanks so much!

Regards

@andyabc123
Copy link

@foolooo I have same problem with you. can you give me full code. thank you very much :)

@foolooo
Copy link

foolooo commented Nov 24, 2013

Hi @andyabc123 , I put @mkraemer 's functions into the demo code. Here is the buyOrder code

    <?php
function sign($method, $params = array()){


    $accessKey = "replace-this"; 
    $secretKey = "replace-this"; 

    $mt = explode(' ', microtime());
    $ts = $mt[1] . substr($mt[0], 2, 6);

    $signature = sprintf(
        'tonce=%s&accesskey=%s&requestmethod=post&id=%s&method=%s&params=%s',
        $ts,
        $accessKey,
        1, //id number
        $method,
        implode(',', $params)
    );
    var_dump($signature);

    $hash = hash_hmac('sha1', $signature, $secretKey);

    return array(
        'ts' => $ts,
        'hash' => $hash,
        'auth' => base64_encode($accessKey.':'. $hash),
    );
}

function request($method, $params){
    $sign = sign($method, $params);

    $options = array( 
        CURLOPT_HTTPHEADER => array(
            'Authorization: Basic ' . $sign['auth'],
            'Json-Rpc-Tonce: ' . $sign['ts'],
        ),
    );

    $postData = json_encode(array(
        'method' => $method,
        'params' => $params,
        'id' => 1,
    ));

    //echo "this is postdata ="; //probe alert added

    print($postData);

    $headers = array(
            'Authorization: Basic ' . $sign['auth'],
            'Json-Rpc-Tonce: ' . $sign['ts'],
        );     

    //echo "\n"."headers = ".$headers."\n";  // probe added

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_USERAGENT, 
            'Mozilla/4.0 (compatible; BTC China Trade Bot; '.php_uname('a').'; PHP/'.phpversion().')'
            );

    curl_setopt($ch, CURLOPT_URL, 'https://api.btcchina.com/api_trade_v1.php');
    curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);

    //echo "\n"."postData = ".$postData."\n"; // probe added

    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);

    // run the query
    $res = curl_exec($ch);

    //echo "base64 = ".$sign['auth']."\n"; // probe added

    return $res;
    /**/
  }

    try { 
        var_dump(request('buyOrder', [5355.660000,0.000000]));

    } catch (Exception $e) {                
            echo "Error:".$e->getMessage();         
    } 


    ?> 

You will need to replace the accessKey and the secretKey, and the price and amount.

Hope it helps.

Regards

@andyabc123
Copy link

Thank you very much,it's work now;)

Andy

ÔÚ 2013Äê11ÔÂ25ÈÕ£¬6:22£¬Bo notifications@github.com дµÀ£º

Hi @andyabc123 , I put @mkraemer 's functions into the demo code. Here is the buyOrder code

$ts, 'hash' => $hash, 'auth' => base64_encode($accessKey.':'. $hash), ); ``` } function request($method, $params){ $sign = sign($method, $params); ``` $options = array( CURLOPT_HTTPHEADER => array( 'Authorization: Basic ' . $sign['auth'], 'Json-Rpc-Tonce: ' . $sign['ts'], ), ); $postData = json_encode(array( 'method' => $method, 'params' => $params, 'id' => 1, )); //echo "this is postdata ="; //probe alert added print($postData); $headers = array( 'Authorization: Basic ' . $sign['auth'], 'Json-Rpc-Tonce: ' . $sign['ts'], ); //echo "\n"."headers = ".$headers."\n"; // probe added $ch = curl_init(); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; BTC China Trade Bot; '.php_uname('a').'; PHP/'.phpversion().')' ); curl_setopt($ch, CURLOPT_URL, 'https://api.btcchina.com/api_trade_v1.php'); curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); //echo "\n"."postData = ".$postData."\n"; // probe added curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // run the query $res = curl_exec($ch); //echo "base64 = ".$sign['auth']."\n"; // probe added return $res; /**/ ``` } ``` try { var_dump(request('buyOrder', [5355.660000,0.000000])); } catch (Exception $e) { echo "Error:".$e->getMessage(); } ``` ?>

You will need to replace the accessKey and the secretKey, and the price and amount.

Hope it helps.

Regards

¡ª
Reply to this email directly or view it on GitHub.

@yarkh
Copy link

yarkh commented Nov 26, 2013

Faced 401 error yesterday on Android. The core of problem was in BTCChinaDigest (digestParams):
It waited for requestJson string format: {"id":1,"method":"getAccountInfo","params":[]}
But actually got: {"params":[],"method":"getAccountInfo","id":1}
So string didn't match Pattern.compile("{"id":([0-9]),"method":"([^\"])","params":[([^\]]*)]}", ...
And we got wrong signature and authentication problem.

alphafoobar pushed a commit to alphafoobar/XChange that referenced this issue Aug 6, 2019
.

This is has some issues with the latest codeset (in particular, it doesn't compile against XChange 4.3.11).
It needs the attention of someone who actually uses BitMex.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests