Problem getting access_token after migrating to OAuth 2.0

前端 未结 4 825
清酒与你
清酒与你 2021-01-05 16:18

I have tried migrating my app to the OAuth 2.0 routine. I am having trouble getting the access_token from the cookie set by the JavaScript API. I decode the information in t

4条回答
  •  失恋的感觉
    2021-01-05 16:57

    Turns out that (even though it is not documented) we need to exchange the code for an access_token ourselves. I think this is a total waste since that was the nice thing about the old cookie. It was fast and easy to get the access_token.

    Anyway. To get the access_token from the new cookie you need to do the following:

    public string ReturnAccessToken()
    {
        HttpCookie cookie = htc.Request.Cookies[string.Format("fbsr_{0}", facebookAppID)];
        string jsoncode = System.Text.ASCIIEncoding.ASCII.GetString(FromBase64ForUrlString(cookie.Value.Split(new char[] { '.' })[1]));
    
        JsonData data = JsonMapper.ToObject(jsoncode);
    
        getAccessToken(data["code"].ToJson()
    }
    
    private string getAccessToken(string code)
    {
        //Notice the empty redirect_uri! And the replace on the code we get from the cookie.
        string url = string.Format("https://graph.facebook.com/oauth/access_token?client_id={0}&redirect_uri={1}&client_secret={2}&code={3}", "YOUR_APP_ID", "", "YOUR_APP_SECRET", code.Replace("\"", ""));
    
        System.Net.HttpWebRequest request = System.Net.WebRequest.Create(url) as System.Net.HttpWebRequest;
        System.Net.HttpWebResponse response = null;
    
        using (response = request.GetResponse() as System.Net.HttpWebResponse)
        {
            System.IO.StreamReader reader = new System.IO.StreamReader(response.GetResponseStream());
    
            string retVal = reader.ReadToEnd();
            return retVal;
        }
    }
    
    public byte[] FromBase64ForUrlString(string base64ForUrlInput)
    {
        int padChars = (base64ForUrlInput.Length % 4) == 0 ? 0 : (4 - (base64ForUrlInput.Length % 4));
        StringBuilder result = new StringBuilder(base64ForUrlInput, base64ForUrlInput.Length + padChars);
        result.Append(String.Empty.PadRight(padChars, '='));
        result.Replace('-', '+');
        result.Replace('_', '/');
        return Convert.FromBase64String(result.ToString());
    }
    

    This may seem a bit redundant, but I suppose you can store the access_token in a session variable. If you do this and iFrame the your app on Facebook you need to know that it will not work in IE 6, 7 and 8 if the user have set his browser privacy settings to medium. There is a workaround for this, but as it is not a part of this question I will not write it. If people really want it, write a comment and I will show it :)

    -----------------------------------EDIT------------------------------------------

    When using any of the old IE browsers you can't use cookies or session variables in pages that are Iframed in, like your pages on Facebook. This is a problem that can't really be solved sufficiently in coding. By sufficiently I mean that the solution is not nice. You need to set the p3p-header in your response. You can of course do this in coding for all the pages that you service, but the easiest solution (if you are using a .NET server to host your pages) is to set up a p3p policy for the IIS. A guide for this can be seen in http://support.microsoft.com/kb/324013. It shouldn't matter what you write in the p3p policy (if you check Facebooks own you can see that they use "We don't have a p3p policy), the important part is that there stands something. I have had troubles just using random text though, but if you use the text in the example there shouldn't be a problem :)

    This took me forever to find out, so I hope someone can use it :D

提交回复
热议问题