Webforms (loading stored credentials)

May 23, 2011 at 5:55 PM

Hi Joe,

  I am able to store the tokens as needed. But for some reason the tokens are partially read. It will read the users timeline and understand that the user is authorized but its not.

I know the problem is in the 2nd credientals part but im stumped why they wont load even tho they are referenced to load.  

I hope other people can also learn since im using your examples as a starting point.  As you can tell in the beginning i was trying to check for exact cookie fields which didnt always work so I lightened up just asked for a cookie with that name,  Then if that was present or not i called the correct authorization method.    I found a few good posts but I am not sure if i should use InMemoryCredientials for the 2nd one and load a string if I already called and stored in the Sessionstate.  But at the end of the day It quasi works but doesnt and I need furthur nudge to get past this hiccup.  I put this in a web control code in a web control and loaded it and works fine.

 

Any help would be appreciated. I know im very close after this the api calls should be cake.

 

using LinqToTwitter;
using System.Configuration;
 
public partial class WebUserControl : System.Web.UI.UserControl
{
    private const string OAuthCredentialsKey = "OAuthCredentialsKey";
 
    private WebAuthorizer auth;
    private TwitterContext twitterCtx;
 
 
 
    protected void Page_Load(object sender, EventArgs e)
    {
 
 
        IOAuthCredentials credentials = new SessionStateCredentials();
 
 
        if (credentials.ConsumerKey == null || credentials.ConsumerSecret == null)
        {
            credentials.ConsumerKey = ConfigurationManager.AppSettings["twitterConsumerKey"];
            credentials.ConsumerSecret = ConfigurationManager.AppSettings["twitterConsumerSecret"];
        }
 
 
 
 
 
 
 
        // if the accesstoken and Oauth is missing do full web work 
        if (Request.QueryString["userInfo"] == null)
 
         //   if (Request.Cookies["userInfo"]["OAuthToken"] == null || Request.Cookies["userInfo"]["AccessToken"] == null)
 
                auth = new WebAuthorizer
                {
                    Credentials = credentials,
                    PerformRedirect = authUrl => Response.Redirect(authUrl)
                };
 
 
 
 
        //   // if accesstoken and OAuth are present. Skip Web Auth and populate keys
        //     if (Request.QueryString["userInfo"] != null)
 
        ////   if (Request.Cookies["userInfo"]["OAuthToken"] != null || Request.Cookies["userInfo"]["AccessToken"] != null)
        //   {
        //       credentials.ConsumerKey = ConfigurationManager.AppSettings["twitterConsumerKey"];
        //       credentials.ConsumerSecret = ConfigurationManager.AppSettings["twitterConsumerSecret"];
        //       credentials.OAuthToken = Server.HtmlEncode(Request.Cookies["userInfo"]["OAuthToken"]);
        //       credentials.AccessToken = Server.HtmlEncode(Request.Cookies["userInfo"]["AccessToken"]);
 
 
 
 
        //       auth = new WebAuthorizer
 
        //        {
 
        //            Credentials = credentials
 
 
        //        };
 
        //   }
 
 
        if (!Page.IsPostBack)
        {
            auth.CompleteAuthorization(Request.Url);
        }
        if (Request.QueryString["userInfo"] == null)
        {
            // stores the cookie values
            HttpCookie userInfo = new HttpCookie("userInfo");
            userInfo.Values["OAuthToken"] = credentials.OAuthToken;
            userInfo.Values["AccessToken"] = credentials.AccessToken;
 
            //  userInfo.Domain = "blahblah.com"; // sets the cookie to the domain
            userInfo.Expires = DateTime.Now.AddYears(1);
            Response.Cookies.Set(userInfo);
 
        }
 
 
 
        if (string.IsNullOrWhiteSpace(credentials.ConsumerKey) ||
            string.IsNullOrWhiteSpace(credentials.ConsumerSecret))
        {
            // The user needs to set up the web.config file to include Twitter consumer key and secret.
            PrivateDataMultiView.SetActiveView(SetupTwitterConsumer);
        }
        // if accesstoken and OAuth are present. Skip Web Auth and populate keys
        if (Request.QueryString["userInfo"] != null)
 
        //   if (Request.Cookies["userInfo"]["OAuthToken"] != null || Request.Cookies["userInfo"]["AccessToken"] != null)
        {
            credentials.ConsumerKey = ConfigurationManager.AppSettings["twitterConsumerKey"];
            credentials.ConsumerSecret = ConfigurationManager.AppSettings["twitterConsumerSecret"];
            credentials.OAuthToken = Server.HtmlEncode(Request.Cookies["userInfo"]["OAuthToken"]);
            credentials.AccessToken = Server.HtmlEncode(Request.Cookies["userInfo"]["AccessToken"]);
 
 
 
 
            auth = new WebAuthorizer
 
            {
 
                Credentials = credentials
 
 
            };
 
        }
        else if (auth.IsAuthorized)
        {
            screenNameLabel.Text = auth.ScreenName;
            PrivateDataMultiView.SetActiveView(ViewPrivateUpdates);
            updateBox.Focus();
        }
        else
        {
            PrivateDataMultiView.SetActiveView(AuthorizeTwitter);
        }
 
        twitterCtx = auth.IsAuthorized ? new TwitterContext(auth) : new TwitterContext();
 
        var tweets =
            from tweet in twitterCtx.Status
            where tweet.Type == (auth.IsAuthorized ? StatusType.Friends : StatusType.Public)
            select tweet;
 
        TwitterListView.DataSource = tweets;
        TwitterListView.DataBind();
    }
 
 
 
    protected override void OnPreRender(EventArgs e)
    {
        base.OnPreRender(e);
 
        if (twitterCtx != null)
        {
            twitterCtx.Dispose();
            twitterCtx = null;
        }
    }
 
    protected void authorizeTwitterButton_Click(object sender, EventArgs e)
    {
        auth.BeginAuthorization(Request.Url);
    }
 
    protected void postUpdateButton_Click(object sender, EventArgs e)
    {
        if (!Page.IsValid)
        {
            return;
        }
 
        twitterCtx.UpdateStatus(updateBox.Text);
        updateBox.Text = string.Empty;
    }
 
}

 

 

 

May 23, 2011 at 11:15 PM
Edited May 23, 2011 at 11:17 PM

my  only other idea would put 2 separate if statements one for ioauthcredentials  and a 2nd for inmemory and if use cook is null do iocredential and isnt null do inmemory and load something like the post example with load string. I dont want to tear up my code unless i have too

 

Help me Joe Kenobi.. your my only hope.

May 25, 2011 at 2:54 AM

hi Joe.

 

  I made some changes to my code after  Cookie is not null to just read and login with the keys. but still the same problem

 

  if (Request.QueryString["userInfo"] != null)
        //   if (Request.Cookies["userInfo"]["OAuthToken"] != null || Request.Cookies["userInfo"]["AccessToken"] != null)
         
      //  auth = new WebAuthorizer
        {
            credentials = new InMemoryCredentials();
            string authString = Session[OAuthCredentialsKey] as string;
 
            if (authString == null)
            {
                credentials.ConsumerKey = ConfigurationManager.AppSettings["twitterConsumerKey"];
                credentials.ConsumerSecret = ConfigurationManager.AppSettings["twitterConsumerSecret"];
                credentials.OAuthToken = Server.HtmlEncode(Request.Cookies["userInfo"]["OAuthToken"]);
                credentials.AccessToken = Server.HtmlEncode(Request.Cookies["userInfo"]["AccessToken"]);
                Session[OAuthCredentialsKey] = credentials.ToString();
            }
            else
            {
                credentials.Load(authString);
            }
            // credentials.Load(auth.Credentials)
 
        }

Im not familar with the OAuth credential key object in the api but i seen it used before. I figured my values would populate it and overwrite it.

I rather call the InMemoryCredentials with the comma separated values but I dont know the overload after the last one because im not going to use the Redirect lambda or web auth
or should i call the object twice ?.

auth = new WebAuthorizer
                {
                    Credentials = credentials,
                    PerformRedirect = authUrl => Response.Redirect(authUrl)
                };

If i been reading enough of the forum posts I should be able to end at credentials.load(thevaluesoftoken) and I should be good to go. If i am wrong pass me a bone. lol

thank you joe.

May 25, 2011 at 5:04 AM

for some reason it will post at times even though the auth,screenname label is blank . I think I might have 2 problems 1 the scope of the auth and the retrieving of the cookies correctly with the loading.

It is saving and retrieving the cookies.

Iocredentials  populate the credentials object as SessionStateCredentials

Then I check for null credential keys and do the auth dance

I come back to the site . They get saved,  The site works great as intended.  I am Happy

Then  I reload

The auth screenlabel doesnt load that would say welcome user but the Auth button view box disapears and shows the post box.

I posted successfully last test even though the label was wrong. 

2 reasons i think,  1 the session was still loaded with the proper cookies and 2 I switched am out of scope of the auth object on the reload but the OAuth works just not the auth.credentials.

 

should i call a 2nd web authorizer and   auth.CompleteAuthorization(Request.Url);        before the load.

 

 

 

May 29, 2011 at 5:44 PM

Hi Everyone

  Can someone throw me a hint or tip?  I am able to store credentials or perform the auth dance without a problem but I cant do both but not together. This post at http://linqtotwitter.codeplex.com/discussions/250352 and the MVC post starter has been the most help.

I am able to get credentials stored but I dont get full access afterwards.  If I do the auth dance the first time the auth.screenname label works.  If i refresh it disapears but my time line stays and I can post to it. I know its broke because the screen name label should appear as well.

 

Am I correct that I do not need to call the this after the credentials are stored?

 

                auth = new WebAuthorizer
                {
                    Credentials = credentials,
                    PerformRedirect = authUrl => Response.Redirect(authUrl)
                };
 

 
 
                if (!Page.IsPostBack)
                {
                   auth.CompleteAuthorization(Request.Url);
                }

I can use a suggestion how to do the load after auth.complete. Every condition i try to use fails Like if cookie is not null or if auth.credentials is null do the auth dance but if isnt load credentials.

I could use a suggestions Im getting bummed out trying for days and getting no where on loading them when I have them saved properly.



Coordinator
May 29, 2011 at 9:14 PM
Edited May 29, 2011 at 9:16 PM

Hi,

It sounds like your stored credentials are not being properly loaded.  The reason I say this is because WebAuthorizer won't do the dance if you've already loaded credentials.  There a property called IsAuthorized, which is true of credentials are loaded.  Both BeginAuthorization and CompleteAuthorization check IsAuthorized and return immediately if true, otherwise they attempt to authenticate.  Set a breakpoint after instantiating WebAuthorizer and look at the value of IsAuthorized.  If it's false, that's telling you that stored credentials aren't loaded.  There are two ways to load credentials, either manually or with the Load helper method:

1. If you were loading credentials manually, you would do something like this:

// Get credentials from DB

var credentials = new InMemoryCredentials();

credentials.ConsumerKey = yourTwitterConsumerKey;

credentials.ConsumerSecret = yourTwitterConsumerSecret;

credentials.OAuthToken = oauthTokenForThisUserFromDB;

credentials.AccessTolken = accessTokenForThisUserFromDB;

2. If you were loading credentials with Load helper method, you could do something like this:

string credentialString = GetCredentialStringFromDB();

var credentials = new InMemoryCredentials();

credentials.Load(credentialString);

// the format of the credential string is "consumerkey,consumerSecret,oauthToken,accessToken".  If you called credentials.ToString() after the first oauth dance and saved the values, the string will already be in the proper format.

The order of operations should go like this:

1. Instantiate and load credentials instance.

2. Instantiate and load WebAuthorizer with credentials.

3. Instantiate TwitterContext with WebAuthorizer.

As a side note, all of these classes are extensible. All I've done is provide some basic classes with default implementation, leaving a great deal of flexibility for users.  i.e. Ff you implement IOAuthCredentials, just like all the other credential stores do, or derive your own class from an existing class provided with LINQ to Twitter that implements IOAuthCredentials you can create your own custom implementation of how credentials are managed.

Edit: BTW, the examples above are pseudo code and are guaranteed *not* to compile if you try to copy and paste. ;)

Joe

May 29, 2011 at 10:06 PM

thank you ill re check.. i just figured out the default aspx demo does the same thing. why does the screen name.label not hold its values on a refresh if its in a session? it can do everything else.  I think i had i might of had it all along.

 

im going to get to work on re checking my code as well as restepping and breakpoints.