Problem Logging Out

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • monkeymagix
    Junior Member
    • Jul 2010
    • 105

    #1

    Problem Logging Out

    I have taken the API_ING example code and extended and fixed it and it's almost there once I have converted it from an app to a DLL.

    However the problem I have is with Logging Out.

    Not logging in which I am doing with my own HTTPRequest class and then storing the session ID in a text file (like the old Soap method) and then passing it back n forth in KeepAlive requests and it seems the logout procedure.

    My code I am using is below.

    Login works.
    Logout doesn't


    Code:
    /* 
    
    this isn't working as I am not passing the session ID in the headers as BDP say
    
    Question:
    Should I be passing back any other cookie value when calling https://identitysso.betfair.com/api/logout and should they be in the URL along with the API key
    and URL e.g &product=XsgVRnmen1RTrGnis&url=https%3a%2f%2fwww.betfair.com%2f or passed as cookies?
    
    Response:
    No, you don't need to pass in any other cookies into the Logout request.  The required headers are:
    
    Accept: application/json
    X-Authentication: <sessionToken>
    
    
    So as you can see from my two Login Logout procs which are for a BOT runs all day from a Windows Service, storing the Session in a text file, and then re-using it for KeepAlives
    and as I should the Logout method. Question is should I even use my own HTTP Request class for POST/GET requests that handles getting/storing cookies, HTTP status errors, timeouts, retries and so on
    */
    
    
    public string Logout()
    {
        string token = "ERROR";
    
        // pass request, product=appkey, URL=logout 
        // should I pass the session in here as well so that the JSON code deocdes the Post values and adds them to headers? e.g soid=SessionValue
        string request = "&" + "product=" + System.Web.HttpUtility.UrlEncode(APPKEY, Encoding.UTF8)
    		    + "&url=" + System.Web.HttpUtility.UrlEncode("https://www.betfair.com/", Encoding.UTF8);
    
        // Make POST Request to Logout URL although here I am not passing the SessionID at all which I should be doing, question is how
        // and should I be using my own HTTP Request object at all?
    
        HTTPRequest http = new HTTPRequest("POST", LogoutURL, request, null, "", true, 30, false, 1, 2, true);
    
        http.MakeHTTPRequest();
    
        if (http.StatusCode == 200)
        {
    	// logged out ok although I should be checking Status FAIL/SUCCESS in reality
    
    	token = "200";
        }
        else
        {
    	token = "0";	
        }
    
        return token;
    
    }
    
    
    // This works! I take the session from the login and save it in a text file for re-use in keepalive and logouts and future requests
    public string Login()
    {
        string token = "ERROR";
    
        string request = "&username=" + System.Web.HttpUtility.UrlEncode(this.Username,Encoding.UTF8)
    		    + "&password=" + System.Web.HttpUtility.UrlEncode(this.Password, Encoding.UTF8)
    		    + "&login=" + System.Web.HttpUtility.UrlEncode("true", Encoding.UTF8)
    		    + "&redirectMethod=" + System.Web.HttpUtility.UrlEncode("POST", Encoding.UTF8)
    		    + "&product=" + System.Web.HttpUtility.UrlEncode("home.betfair.int", Encoding.UTF8)
    		    + "&url=" + System.Web.HttpUtility.UrlEncode("https://www.betfair.com/", Encoding.UTF8);
     
        // create new instance of my HTTP object with a POST, the URL, the data, timeouts, whether to get body, retrieve cookies, retry etc
        HTTPRequest http = new HTTPRequest("POST", LoginURL, request, null, "", true, 30, false, 1, 2, true);
    
        HelperLib.LogMsg("Make POST HTTP Request to " + LoginURL);
    
        // make my POST request to the login URL
        http.MakeHTTPRequest();
    
        if (http.StatusCode == 200)
        {
    	this.HelperLib.LogMsg("We got a 200 status code logging in - check cookie for ssoid");
    
    	// get sesssion Id from ssoid cookie value, and store in session.txt file so we can keepAlive and re-use it on each call
    	this.SessionCode = http.GetCookieValue("ssoid");
    
    	// Logged in ok
    	token = "200";
        }
        else
        {
    	this.HelperLib.LogMsg("Could not login; Error: " + http.Error + "; " + http.StatusDescription + ";");
        }
    
        return token;
        
    }


    The code in the actual JSON RescriptClient class (you can download all this from the C# example API-ING libray they put on their site >https://github.com/betfair/API-NG-sa.../master/cSharp


    Code:
    public class RescriptClient : HttpWebClientProtocol, IClient
        {
            public NameValueCollection CustomHeaders { get; set; }
    
    	// this is what i use to login should I be using it logout as well?
    	public RescriptClient(string endPoint, string appKey, string sessionToken)
    	{
                this.HelperLib = new HelperLib();
    
                HelperLib.LogMsg("In RescriptClient endPoint before adding /rest/v1.0/ to it is " + endPoint);
    
                this.EndPoint = endPoint + "/rest/v1.0/";
    
                HelperLib.LogMsg("Now its " + this.EndPoint + " appKey = " + appKey + " sessionToken = " + sessionToken);
                
                CustomHeaders = new NameValueCollection();
                if (appKey != null)
                {
                    CustomHeaders[APPKEY_HEADER] = appKey;
                }
                if (sessionToken != null)
                {
                    CustomHeaders[SESSION_TOKEN_HEADER] = sessionToken;
                }
    	}
    
    	// I guess this is going over my own class methods?
    	protected HttpWebRequest CreateWebRequest(String restEndPoint)
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(restEndPoint);
                request.Method = "POST";
                request.ContentType = "application/json";
                request.ContentLength = 0;
                request.Headers.Add(HttpRequestHeader.AcceptCharset, "UTF-8");
                request.Accept = "application/json";
                request.Headers.Add(CustomHeaders);
                return request;
            }
    
    	// then the invoke method that converts it all to JSON etc
    	public T Invoke<T>(string method, IDictionary<string, object> args = null)
            {
                if (method == null)
                    throw new ArgumentNullException("method");
                if (method.Length == 0)
                    throw new ArgumentException(null, "method");
    
                var restEndpoint = EndPoint + method + "/";
                var request = CreateWebRequest(restEndpoint);
    
                var postData = JsonConvert.Serialize<IDictionary<string, object>>(args) + "}";
    
                Console.WriteLine("\nCalling: " + method + " With args: " + postData);
    
                var bytes = Encoding.GetEncoding("UTF-8").GetBytes(postData);
                request.ContentLength = bytes.Length;
    
                using (Stream stream = request.GetRequestStream())
                {
                    stream.Write(bytes, 0, bytes.Length);
                }
    
                using (HttpWebResponse response = (HttpWebResponse)GetWebResponse(request))
               
                using (Stream stream = response.GetResponseStream())
                using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
                {
    
                    var jsonResponse = reader.ReadToEnd();
                    Console.WriteLine("\nGot response: " + jsonResponse);
                    
                    if (response.StatusCode != HttpStatusCode.OK) {
                        throw ReconstituteException(JsonConvert.Deserialize<Api_ng_sample_code.TO.Exception>(jsonResponse));
                    }
                    return JsonConvert.Deserialize<T>(jsonResponse);
    
                }
            }
    }
    So what is my best course of action?

    Rewrite my code - or just use their own code that extends HTTPResponse.

    I just need the line of code to pass into the method to logout a bit like the Login function which passes appkey and username in as request params e.g

    string request = "&" + "product=" + System.Web.HttpUtility.UrlEncode(APPKEY, Encoding.UTF8)
    + "&url=" + System.Web.HttpUtility.UrlEncode("https://www.betfair.com/", Encoding.UTF8);


    So could I not do something similar but pass in SessionID as well?

    I am off work sick trying to do this with a bad leg and not very well at all due to all the anti biotics and pain killers so sorry if I am not very clear etc. I just want to be able to logout without these errors.

    At the moment here is the debug of the code I am using with values changed to protect the guilty etc.

    In RescriptLogin
    Try Logging in to the API with RescriptLogin = https://api.betfair.com/exchange/betting, dGdjUEjHHhhr22ee, 0dRtNLbRTJw7sNRy4d49kifppWrlEj+NhRge1ZvVl7Jfol
    In RescriptClient endPoint before adding /rest/v1.0/ to it is https://api.betfair.com/exchange/betting
    Now its https://api.betfair.com/exchange/betting/rest/v1.0/ appKey = dGdjUEjHHhhr22ee sessionToken = 0dRtNLbRTJw7sNRy4d49kifppWrlEj+NhRge1ZvVl7Jfol
    this.Client should be populated
    Try Logging in to the account with RescriptLogin = https://api.betfair.com/exchange/account, dGdjUEjHHhhr22ee, 0dRtNLbRTJw7sNRy4d49kifppWrlEj+NhRge1ZvVl7Jfol
    In RescriptClient endPoint before adding /rest/v1.0/ to it is https://api.betfair.com/exchange/account
    Now its https://api.betfair.com/exchange/account/rest/v1.0/ appKey = dGdjUEjHHhhr22ee sessionToken = 0dRtNLbRTJw7sNRy4d49kifppWrlEj+NhRge1ZvVl7Jfol
    this.Account should be populated
    RETURN True
    Rescript Login Worked!
    We can login - Save Session
    Save Session: 0dRtNLbRTJw7sNRy4d49kifppWrlEj+NhRge1ZvVl7Jfol for SystemName: Main System
    Save Session to C:\ProgramData\Brainiac\betfairsession.txt
    IN RunJobs - Job: CHECHECKFUNDS
    Ran CHECHECKFUNDS OK!
    Now dispose of Control object
    LOGOUT
    Logout from https://identitysso.betfair.com/api/logout with this post data = &product=dGdjUEjHHhhr22ee&url=https%3a%2f%2fwww.be tfair.com%2f&ssoid=0dRtNLbRTJw7sNRy4%2bNhRge1ZvVl7 Jfol8xIVMEgTr4
    IN HTTPRequest POST - https://identitysso.betfair.com/api/logout - &product=dGdjUEjHHhhr22ee&url=https%3a%2f%2fwww.be tfair.com%2f&ssoid=0dRtNLbRTJw7sNRy4%2bNhRge1ZvVl7 Jfol8xIVMEgTr4 -
    End of Init
    Access the URL
    IN Access URL
    MAKE POST REQUEST TO https://identitysso.betfair.com/api/logout
    Make a POST request to https://identitysso.betfair.com/api/logout
    make request with Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.57 Safari/537.36
    Convert post data into stream = &product=dGdjUEjHHhhr22ee&url=https%3a%2f%2fwww.be tfair.com%2f&ssoid=0dRtNLbRTJw7sNRy4%2bNhRge1ZvVl7 Jfol8xIVMEgTr4
    response.ContentEncoding =
    response.ContentType = text/html;charset=UTF-8
    Status of request = OK
    Add cookie = mSsoToken=""
    Add cookie = ssoid=""
    Add cookie = loggedIn=""
    Add cookie = lka=""
    Add cookie = JSESSIONID=227424B815F81E88CD076849954761D7
    Now get the full response back
    Got stream ok
    Response back is <html>
    <head>
    <title>Logout error</title>
    </head>
    <body onload="document.logout.submit()">
    <form name="logout" action="https://www.betfair.com/" method="POST">
    <input type="hidden" name="errorCode" value="NO_SESSION"/>
    </form>
    </body>
    </html>
    Got 200 Status Code!
    Logged Out Okay!
    The control object has been disposed
    RETURN FROM PROGRAM MAIN
    Job Finished


    As you can see I did try adding the SSOID (SessionID) into the URL request string e.g

    Convert post data into stream = &product=XsgGQnwt673HTrGnis&url=https%3a%2f%2fwww. betfair.com%2f&ssoid=0dRtNLbRTJw7sNRy4%2bNhRge1ZvVl7Jfol8xIVMEgTr 4

    Which didn't work.

    Response back from my email to BDP is

    b) I don't know whether I should be re-supplying my current Session Cookie as the value of ssoid?

    To logout you should provide the most recent valid session token.

    c) should I be passing back any other cookie value when calling https://identitysso.betfair.com/api/logout and should they be in the URL along with the API key
    and URL e.g &product=XsgGRtThgTYDfeqrGnis&url=https%3a%2f%2fww w.betfair.com%2f or passed as cookies?

    No, you don't need to pass in any other cookies into the Logout request. The required headers are:

    Accept: application/json
    X-Authentication: <sessionToken>

    For successful login/logout you should check the 'status' value returned in the response which will be SUCCESS/FAIL and take the necessary action.
    token: "sessionToken"
    product: "AppKey"
    status: "FAIL"
    error: "NO_SESSION"


    What is the best way of doing this with the code I HAVE and am USING (no new code please from "just do this" etc people) it's a big C# DLL library with lots of classes.

    I have handled the "no app.config" in DLLs by using XML but just stuck on this logout as I don't get why the login works but logout doesn't.

    Any real help would be much appreciated.

    Thanks!
Working...
X