I have been banging my head over this the whole day. I am trying to access StockTwits API (https://api.stocktwits.com/developers) from an R session. I have earlier accessed the twitter API (via rtweet) without hassles.
I have created an app and got the client id and key (the below are just examples).
app_name = "some.name";
consumer_key = "my_client_id";
consumer_secret = "my_client_key";
uri = "http://iimb.ac.in" # this is my institute's homepage. It doesn't allow locahost OR 127.0.0.1
scope = "read,watch_lists,publish_messages,publish_watch_lists,direct_messages,follow_users,follow_stocks";
base_url = "https://api.stocktwits.com/api/2/oauth"; # see https://api.stocktwits.com/developers/docs/api
The procedure is to create an oauth2.0 app and endpoint. Then call oauth2.0_token.
oa = httr::oauth_app(app_name, key = consumer_key, secret = consumer_secret, redirect_uri = uri);
oe = httr::oauth_endpoint("stocktwits", "authorize", "token", base_url = base_url);
mytoken = httr::oauth2.0_token(oe, oa, user_params = list(resource = base_url), use_oob = F); # use_oob = T doesn't work.
After firing the above, it takes me to the browser for sign-in. I sign-in and it asks me to connect. After that, I am taken back to my URI plus a code, i.e. https://www.iimb.ac.in/?code=295ea3114c3d8680a0ed295d52313d7092dd90ae&state=j9jXzEqri1
Is the code my access token or something else? The oauth2.0_token() call keeps waiting for the code since the callback is not localhost. I didn't seem to get a hang of that.
I then try to access the API using the above code as access token but I am thrown "invalid access token" error. The format is described in https://api.stocktwits.com/developers/docs/api#search-index-docs
Can someone tell me what I have missed? If required I can share my app_name, consumer_key and consumer_secret for replication.
Related
I am trying to test out the Dun and Bradstreet API in R using httr.
I am trying to leverage the oauth2 functionality in httr.
Here is my code:
library(httr)
library(jsonlite)
clientid = redacted
secret = redacted
app <- oauth_app(appname = "Dun", key = clientid, secret = secret)
endpoint <- oauth_endpoint(base_url = "https://login.bisnode.com/sandbox/v1/token.oauth2", authorize="https://login.bisnode.com/sandbox/v1/token.oauth2", access = "https://login.bisnode.com/sandbox/v1/token.oauth2")
token <- oauth2.0_token(endpoint = endpoint, app = app, scope = "credit_data_companies", user_params = list(grant_type = "client_credentials"))
In Rstudio I get this message:
Waiting for authentication in browser... Press Esc/Ctrl + C to abort
In the browser, I get this message:
{"error":"invalid_request","error_description":"grant_type is
missing"}
I am sure this is something simple, but I could not find a solution in any other posts. Thank you!
I use Oauth2 authorization to get the token for REST API. I tested the setting in SoapUI and it is working with the Resource Owner Password Credential Grant as shown below.
The setting in the SoapUI testing is working
Now, I want to retrieve the token through R httr library, but I don’t know how to set the resource owner name and password in the R code. Here is my Code
library(httr)
library(jsonlite)
r <- POST("https://XXXXXXX.com/authservice/connect/token",
config = list(),
body = list(
# grant_type = "RESOURCE_OWNER_PASSWORD_CREDENTIALS",
grant_type = "resource_owner_credentials",
resourceOwnerName = "ResourceName",
resourceOwnerPassword = "Resourcepwd",
# resource_Owner_Name = "ResourceName",
# resource_Owner_Password = "Resourcepwd",
# resourceOwner_Name = "ResourceName",
# resourceOwner_Password = "Resourcepwd",
# resource_OwnerName = "ResourceName",
# resource_OwnerPassword = "Resourcepwd",
# resource_Name = "ResourceName",
# resource_Password = "Resourcepwd",
# resource_id = "ResourceName",
# resource_secret = "Resourcepwd",
client_id = "ClientIDname",
client_secret = "Clientpassword",
scope = "xxxGroup"
),
encode = "form"
)
warn_for_status(r)
content(r)
status_code(r)
I got a 400 error ("unsupported_grant_type" and bad request). I am guessing there may be something wrong with the syntax on the resource onwer name and password, so I also tried all the possible combinations that I commented in above code but they all failed.
My question is: are the parameter names for both resource owner name and password pre-defined by the API document, or they are the fixed names defined by R-httr librabry, regardless what token authorization service?
Can someone help to take a look at? Any input is greatly appreciate!
Resolved
I am using the following R code to acquire a token from Reddit API on behalf of a user. However, tokens expire in an hour. To keep access with that app, I need to use a refresh_token parameter that I would receive with a first request, I understand. However, for some reason, I cannot receive a refresh_token using the following code:
#API app settings reddit:
endpoint <- oauth_endpoint(
authorize = "https://www.reddit.com/api/v1/authorize",
access = "https://www.reddit.com/api/v1/access_token"
)
appName <- "xxx"
key <- "xxx"
secret <- "xxx"
app <- oauth_app(appName, key, secret)
# authenticate using OAuth2 [an issue with token]
token <- oauth2.0_token(
endpoint = endpoint,
app=app,
scope = c("read"),
user_params = list(duration = "permanent"),
use_basic_auth = TRUE,
config_init = user_agent("Testing"),
cache = TRUE
)
That's how the resulted token looks like:
print(token$credentials)
$access_token
[1] "xxx"
$token_type
[1] "bearer"
$expires_in
[1] 3600
$scope
[1] "read"
Would anybody please suggest how to improve this request?
The request should include duration = "permanent" attribute in query_authorize_extra field
Here is a corrected request:
token <- oauth2.0_token(
endpoint = endpoint,
app=app,
scope = c("read"),
query_authorize_extra = list(duration = "permanent"),
use_basic_auth = TRUE,
config_init = user_agent("Testing"),
cache = TRUE
)
In one hour, token updates itself automatically ones a get or other type of request sent
Here is the OAuth library I'm using: https://github.com/danielcrenna/oauth
I'm getting the token, secret and realmId (company id) just fine and storing them, but when I go to do a simple request, I get (401) Unauthorized.
Here's the code I'm using:
var rq = new OAuthRequest
{
Method = "GET",
Type = OAuthRequestType.ProtectedResource,
SignatureMethod = OAuthSignatureMethod.HmacSha1,
ConsumerKey = ConfigurationManager.AppSettings["ConsumerKey"],
ConsumerSecret = ConfigurationManager.AppSettings["ConsumerSecret"],
Token = requestToken,
TokenSecret = requestTokenSecret,
RequestUrl = "https://quickbooks.api.intuit.com/v3/company/" + realmId + "/query?query=select%20%2A%20from%20CompanyInfo&minorversion=4",
Version = "1.0",
};
And the Auth header:
OAuth oauth_consumer_key="****",oauth_nonce="6su4ljd2is5bxns4",oauth_signature="0taFXiouzOkpK258tz%2Fc%2F2fVQ0c%3D",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1461339515",oauth_token="****",oauth_version="1.0"
I can't find any other details in the error, I'm just getting "401 Unauthorized." How do I get this request to go through?
Oauth is pretty strict in how the header is written. Why not use one of the Libraries already provided by Intuit? or use the API Explorer to view the header and compare to your request header?
The order of the oauth header parameters matter, and version is not the last one. See this guide.
https://developer.intuit.com/docs/0050_quickbooks_api/0010_your_first_request/rest_essentials_for_the_quickbooks_api
I am trying to use the google analytics apis v3 to embed the analytics graph to my website using Certificate file. I got it to work on the local machine but when I deploy the code to my web server it produces this error:
The remote server returned an error: (400) Bad Request.
Does anyone know what is causing this error message and why I can't get the google graph on my production website?
Here is the code that is working on my local machine:
string scope = AnalyticsService.Scopes.AnalyticsReadonly.GetStringValue(),
x509Certificate2File = HttpContext.Current.Server.MapPath("~/App_Data/privatekey.p12"),
x509Certificate2FilePassword = "notasecret",
serviceAccountId = "xxxxxxx#developer.gserviceaccount.com",
profileId = "ga:xxxxxxxx",
startDate = "2013-10-06",
endDate = "2013-11-07";
AuthorizationServerDescription desc = GoogleAuthenticationServer.Description;
X509Certificate2 key = new X509Certificate2(x509Certificate2File, x509Certificate2FilePassword, X509KeyStorageFlags.Exportable);
AssertionFlowClient client = new AssertionFlowClient(desc, key) { ServiceAccountId = serviceAccountId, Scope = scope };
OAuth2Authenticator<AssertionFlowClient> auth = new OAuth2Authenticator<AssertionFlowClient>(client, AssertionFlowClient.GetState);
AnalyticsService gas = new AnalyticsService(new BaseClientService.Initializer() { Authenticator = auth });
DataResource.GaResource.GetRequest request = gas.Data.Ga.Get(profileId, startDate, endDate, "ga:visits");
request.Dimensions = "ga:day";
request.MaxResults = 10;
/* error 400 occur here on the production */
Google.Apis.Analytics.v3.Data.GaData data = request.Execute();
Thanks
There is only one possibility and without looking at the code you're going to have to chase it down; one of the paths are wrong and needs to be changed. This could be in the form of an IP address as well when I say "path" as you are calling something that is not there. It worked fine on your local machine (correct path) and it gave a 400 on the remote one (bad request) as in calling the wrong place.