DropNet unable to save Access Token for consequent requests? - c#

As many people before me, I'm failing miserably to successfully save an access token between launches of my application. This application is actually only going to be used with one specific dropbox account, though I'm trying to make it easy to set up and a bit more dynamic.
Of course, if the settings are empty (initial run), the user can correctly log in and authorize the app, and coming back to the app it works as intended. On subsequent runs, however, when it grabs the token and secret from the settings collection it fails miserably with
Received Response [Unauthorized] : Expected to see [OK]. The HTTP
response was [{"error": "Invalid signature."}].
I'm obviously doing something wrong, what is it? Thanks!
Code below!
using System;
using DropNet;
namespace DS_Uploader_DropBox {
class Program {
private const string AppKey = "my super secret app key";
private const string AppSecret = "my super secret app secret";
static void Main(string[] args) {
DropNetClient client;
DropNet.Models.UserLogin token;
string userToken = Settings.Default.userToken;
string userSecret = Settings.Default.userSecret;
bool needAccessToken = (String.IsNullOrEmpty(userToken) || string.IsNullOrEmpty(userSecret));
//needAccessToken = true;
if (needAccessToken) {
client = new DropNet.DropNetClient(AppKey, AppSecret);
client.UseSandbox = true;
client.GetToken();
// Auth with dropbox
var url = client.BuildAuthorizeUrl();
// Prompt for user to auth
Console.WriteLine("go auth here " + url);
Console.ReadLine();
// If the user authed, let's get that token
try {
token = client.GetAccessToken();
}
catch (Exception e) {
Console.WriteLine("Exception! " + e.Message);
return;
}
// save for later
userToken = token.Token;
userSecret = token.Secret;
Settings.Default.userToken = userToken;
Settings.Default.userSecret = userSecret;
Settings.Default.Save();
} else {
client = new DropNet.DropNetClient(AppKey, AppSecret, userToken, userSecret);
client.UseSandbox = true;
client.GetToken();
// get that token
try {
token = client.GetAccessToken();
} catch (Exception e) {
Console.WriteLine("Exception! " + e.Message);
return;
}
}
var acctInfo = client.AccountInfo();
Console.WriteLine(acctInfo.display_name);
Console.ReadLine();
}
}
}
Code that worked to follow:
using System;
using DropNet;
namespace DS_Uploader_DropBox {
class Program {
private const string AppKey = "my super secret app key";
private const string AppSecret = "my super secret app secret";
static void Main(string[] args) {
DropNetClient client;
DropNet.Models.UserLogin token;
string userToken = Settings.Default.userToken;
string userSecret = Settings.Default.userSecret;
bool needAccessToken = (String.IsNullOrEmpty(userToken) || string.IsNullOrEmpty(userSecret));
//needAccessToken = true;
if (needAccessToken) {
client = new DropNet.DropNetClient(AppKey, AppSecret);
client.UseSandbox = true;
client.GetToken();
// Auth with dropbox
var url = client.BuildAuthorizeUrl();
// Prompt for user to auth
Console.WriteLine("go auth here " + url);
Console.ReadLine();
// If the user authed, let's get that token
try {
token = client.GetAccessToken();
}
catch (Exception e) {
Console.WriteLine("Exception! " + e.Message);
return;
}
// save for later
userToken = token.Token;
userSecret = token.Secret;
Settings.Default.userToken = userToken;
Settings.Default.userSecret = userSecret;
Settings.Default.Save();
} else {
client = new DropNet.DropNetClient(AppKey, AppSecret, userToken, userSecret);
client.UseSandbox = true;
}
var acctInfo = client.AccountInfo();
Console.WriteLine(acctInfo.display_name);
Console.ReadLine();
}
}
}

In the code path where needAccessToken is false, you're calling GetToken and GetAccessToken again, in an attempt to get a new request token and a new access token, respectively. This is unnecessary, as you already have and retrieved the existing access token in userToken and userSecret.

Related

Sign In - Cognito & .Net Framework

I'm trying to connect to AWS Cognito from a .net Framework project.
I can sign up succesfully but when I need to sign in, throws me an error: "User pool {userPool} client does not exist".
This is my code:
private async Task<bool> CheckPasswordAsync(string userName, string password)
{
try
{
var authReq = new AdminInitiateAuthRequest
{
UserPoolId = ConfigurationManager.AppSettings["USERPOOL_ID"],
ClientId = ConfigurationManager.AppSettings["CLIENT_ID"],
AuthFlow = AuthFlowType.ADMIN_NO_SRP_AUTH,
};
authReq.AuthParameters.Add("USERNAME", userName);
authReq.AuthParameters.Add("PASSWORD", password);
AdminInitiateAuthResponse authResp = await _client.AdminInitiateAuthAsync(authReq);
var auts = authResp;
return true;
}
catch(Exception ex)
{
var exc = ex.Message;
return false;
}
}
I don't know if I need to ad more information to the method.
The user pool exists and is the same that I have in appSettings.
Any idea about what's wrong?
Thanks in advance.

InstaSharper Token

I am trying to learn how to use InstaSharper but I've got a problem. Everytime when I run my code to see the new code working, I have to login, but if I do this too many times, I will be blocked by Instagram. I was blocked on two accounts allready. So I need a solution not to always have to login like a token or something.
My login:
public static async void Login()
{
api = InstaApiBuilder.CreateBuilder()
.SetUser(user)
.UseLogger(new DebugLogger(LogLevel.Exceptions))
.SetRequestDelay(RequestDelay.FromSeconds(5, 10))
.Build();
var loginRequest = await api.LoginAsync();
if (loginRequest.Succeeded)
{
Console.WriteLine("Login In Success!");
Follow("artofbokeh");
}
else
{
Console.WriteLine("Login Failed");
}
}
Yes you can save your state in a a file and load it again.
Please give this piece of code a try, it is taken form the official github repo which can be found under this link: Github repo
// create user session data and provide login details
var userSession = new UserSessionData
{
UserName = "username",
Password = "password"
};
// create new InstaApi instance using Builder
_instaApi = InstaApiBuilder.CreateBuilder()
.SetUser(userSession)
.UseLogger(new DebugLogger(LogLevel.Exceptions)) // use logger for requests and debug messages
.SetRequestDelay(TimeSpan.FromSeconds(2))
.Build();
const string stateFile = "state.bin";
try
{
if (File.Exists(stateFile))
{
Console.WriteLine("Loading state from file");
Stream fs = File.OpenRead(stateFile);
fs.Seek(0, SeekOrigin.Begin);
_instaApi.LoadStateDataFromStream(fs);
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
if (!_instaApi.IsUserAuthenticated)
{
// login
Console.WriteLine($"Logging in as {userSession.UserName}");
var logInResult = await _instaApi.LoginAsync();
if (!logInResult.Succeeded)
{
Console.WriteLine($"Unable to login: {logInResult.Info.Message}");
return false;
}
}
var state = _instaApi.GetStateDataAsStream();
using (var fileStream = File.Create(stateFile))
{
state.Seek(0, SeekOrigin.Begin);
state.CopyTo(fileStream);
}
Edit the function to get the state data does the following:
public Stream GetStateDataAsStream()
{
var state = new StateData
{
DeviceInfo = _deviceInfo,
IsAuthenticated = IsUserAuthenticated,
UserSession = _user,
Cookies = _httpRequestProcessor.HttpHandler.CookieContainer
};
return SerializationHelper.SerializeToStream(state);
}
So yes you save all needed information to not login everytime. If this doesnt work for you you are doing something wrong. Please post your code where you load / save the state file.

Remembering log in credentials/permissions UWP/C# (Microsoft Cloud API)

I'm creating an app that access the Microsoft Cloud API to get health data. It uses OAuth to log in when you hit the Sign In Button
private void signinButton_Click(object sender, RoutedEventArgs e)
{
UriBuilder uri = new UriBuilder("https://login.live.com/oauth20_authorize.srf");
var query = new StringBuilder();
query.AppendFormat("redirect_uri={0}", Uri.EscapeDataString(RedirectUri));
query.AppendFormat("&client_id={0}", Uri.EscapeDataString(ClientId));
query.AppendFormat("&scope={0}", Uri.EscapeDataString(Scopes));
query.Append("&response_type=code");
uri.Query = query.ToString();
this.webView.Visibility = Visibility.Visible;
this.webView.Navigate(uri.Uri);
}
This brings up a webView with the page to log in using Microsoft credentials. Once completed, it leads to this:
private async void WebView_NavigationCompleted(WebView sender, WebViewNavigationCompletedEventArgs args)
{
//
// When the web view navigates to our redirect URI, extract the authorization code from
// the URI and use it to fetch our access token. If no authorization code is present,
// we're completing a sign-out flow.
//
if (args.Uri.LocalPath.StartsWith("/oauth20_desktop.srf", StringComparison.OrdinalIgnoreCase))
{
WwwFormUrlDecoder decoder = new WwwFormUrlDecoder(args.Uri.Query);
var code = decoder.FirstOrDefault((entry) => entry.Name.Equals("code", StringComparison.OrdinalIgnoreCase));
var error = decoder.FirstOrDefault((entry) => entry.Name.Equals("error", StringComparison.OrdinalIgnoreCase));
var errorDesc = decoder.FirstOrDefault((entry) => entry.Name.Equals("error_description", StringComparison.OrdinalIgnoreCase));
// Check the code to see if this is sign-in or sign-out
if (code != null)
{
// Hide the browser again, no matter what happened...
sender.Visibility = Visibility.Collapsed;
if (error != null)
{
this.responseText.Text = string.Format("{0}\r\n{1}", error.Value, errorDesc.Value);
return;
}
var tokenError = await this.GetToken(code.Value, false);
if (string.IsNullOrEmpty(tokenError))
{
this.responseText.Text = "Successful sign-in!";
this.signoutButton.IsEnabled = true;
this.signinButton.IsEnabled = false;
this.getProfileButton.IsEnabled = true;
this.getDevicesButton.IsEnabled = true;
this.getActivitiesButton.IsEnabled = true;
this.getDailySummaryButton.IsEnabled = true;
this.getHourlySummaryButton.IsEnabled = true;
}
else
{
this.responseText.Text = tokenError;
}
}
else
{
this.responseText.Text = "Successful sign-out!";
this.signoutButton.IsEnabled = false;
this.signinButton.IsEnabled = true;
this.getProfileButton.IsEnabled = false;
this.getDevicesButton.IsEnabled = false;
this.getActivitiesButton.IsEnabled = false;
this.getDailySummaryButton.IsEnabled = true;
this.getHourlySummaryButton.IsEnabled = false;
}
}
}
private async Task<string> GetToken(string code, bool isRefresh)
{
UriBuilder uri = new UriBuilder("https://login.live.com/oauth20_token.srf");
var query = new StringBuilder();
query.AppendFormat("redirect_uri={0}", Uri.EscapeDataString(RedirectUri));
query.AppendFormat("&client_id={0}", Uri.EscapeDataString(ClientId));
query.AppendFormat("&client_secret={0}", Uri.EscapeDataString(ClientSecret));
if (isRefresh)
{
query.AppendFormat("&refresh_token={0}", Uri.EscapeDataString(code));
query.Append("&grant_type=refresh_token");
}
else
{
query.AppendFormat("&code={0}", Uri.EscapeDataString(code));
query.Append("&grant_type=authorization_code");
}
uri.Query = query.ToString();
var request = WebRequest.Create(uri.Uri);
try
{
using (var response = await request.GetResponseAsync())
{
using (var stream = response.GetResponseStream())
{
using (var streamReader = new StreamReader(stream))
{
var responseString = streamReader.ReadToEnd();
var jsonResponse = JObject.Parse(responseString);
this.creds.AccessToken = (string)jsonResponse["access_token"];
this.creds.ExpiresIn = (long)jsonResponse["expires_in"];
this.creds.RefreshToken = (string)jsonResponse["refresh_token"];
string error = (string)jsonResponse["error"];
return error;
}
}
}
}
catch (Exception ex)
{
return ex.Message;
}
}
I don't want users to have to accept the permissions every time the app is launched. Is there a way to save credentials locally so that it automatically authenticates on launch? Thanks!
You can use
Windows.Storage.ApplicationData.Current.LocalSettings
This process good described by this answer Best Way to keep Settings for a WinRT App?
The code in link identity to UWP
Store the needed oauth parts in the credential locker API. Never store these kind of information in the normal settings API.
On start read the oauth information and use the refreshtoken to get a new access token.
More Information here.
https://msdn.microsoft.com/en-us/library/windows/apps/mt270189.aspx

LinqToTwitter status update only works sometimes

I'm trying to send a tweet using LinqToTwitter. My problem is that it almost never works. I've gotten it to work maybe three times out of thirty, and usually that's when I try to debug. I'm thinking it might have something to do with timing and authentication, but I don't know how to do it. The code runs without errors, but no tweet is generated.
public static async Task SendTweetAsync(string text)
{
// Get the authorization credentials
var auth = GetCredentials();
// Create the twitter context
var ctx = new TwitterContext(auth);
try
{
Status responseTweet = await ctx.TweetAsync(text);
}
catch (Exception e) {
throw e;
}
}
private static AspNetAuthorizer GetCredentials()
{
return new AspNetAuthorizer
{
CredentialStore = new InMemoryCredentialStore()
{
ConsumerSecret = "##########",
ConsumerKey = "##########",
OAuthToken = "##########",
OAuthTokenSecret = "##########",
UserID = ##########
}
};
}
I don't know what happened to the answer that was here before, by #JoeMayo, but the thing that worked for me was to change the AspNetAuthorizer to SingleUserAuthorizer.
private static SingleUserAuthorizer GetCredentials()
{
return new SingleUserAuthorizer
{
CredentialStore = new InMemoryCredentialStore()
{
ConsumerSecret = "##########",
ConsumerKey = "##########",
OAuthToken = "##########",
OAuthTokenSecret = "##########",
UserID = ##########
}
};
}
Also, I added await auth.AuthorizeAsync();
var auth = GetCredentials();
await auth.AuthorizeAsync();
As I said, the credit should really go to #JoeMayo, but his answer is gone.

how to update twitter status from my asp.net web page

I have created an asp.net web page and I am using twitterizer.framework.dll.
Below is my c# code.
protected void btnTwitt_Click(object sender, EventArgs e)
{
//OAuthTokens tokens = new OAuthTokens();
//tokens.AccessToken = "--REDACTED--";
//tokens.AccessTokenSecret = "--REDACTED--";
//tokens.ConsumerKey = "--REDACTED--";
//tokens.ConsumerSecret = "--REDACTED--";
/////
//TwitterResponse<TwitterUser> showUserResponse = TwitterUser.Show(tokens, "twit_er_izer");
string TwitterUserName = "My twitter username";
string TwitterPassword = "my password";
// string TwitterMessage = txtShout.Text;
if (TwitterUserName != string.Empty && TwitterPassword != string.Empty)
{
try
{
//Twitter
// TwitterAccount twitter = new TwitterAccount(TwitterUserName, TwitterPassword);
//Twitter tw
Twitter twitter = new Twitter(TwitterUserName, TwitterPassword);
string TwitterMsg = txtShout.Text;
if (txtShout.Text.Length > 120)
{
TwitterMsg = TwitterMsg.Substring(0, 130) + "... For more update logon to DailyFreeCode.com";
}
else
{
TwitterMsg = TwitterMsg + "... For more update logon to DailyFreeCode.com";
}
twitter.Status.Update(TwitterMsg);
//Twitterizer.TwitterStatus.Update(tokens,TwitterMsg);
lblTwitMsg.Text = "Your have shout successfully on http://twitter.com/" + TwitterUserName;
}
catch (Exception ex)
{
Response.Write("<b>" + ex.Message + "</b><br>" + ex.StackTrace);
}
}
}
Now, I am getting error authorization failed.
On this line
twitter.Status.Update(TwitterMsg);
Plz help me, thanks!
It appears as though you're using Twitterizer version 1.x, but trying to copy code examples from Twitterizer version 2.x. Twitter twitter = new Twitter(TwitterUserName, TwitterPassword); is a dead giveaway. 2.x no longer uses that syntax.
Twitter no longer allows access to the API by supplying username and password. The tokens ARE your username and password, in a manner of speaking.
If you use the twitterizer framework you shouldn't be passing the username/password. You need to fill:
OAuthTokens tokens = new OAuthTokens();
tokens.AccessToken = "XXX";
tokens.AccessTokenSecret = "XXX";
tokens.ConsumerKey = "XXX";
tokens.ConsumerSecret = "XXX";
you can do this by using the following three methods from the framework:
1:
public static Uri BuildAuthorizationUri(
string requestToken
)
2:
public static OAuthTokenResponse GetRequestToken(
string consumerKey,
string consumerSecret,
string callbackAddress
)
3:
OAuthTokenResponse accessToken = OAuthUtility.GetAccessToken(consumerKey, consumerSecret, requestToken, verifier);
look it up here

Categories

Resources