I am using Oauth to connect to Twitter, but it results in a 401 error. What am I doing wrong here?
//config
define('CONSUMER_KEY',"");
define('CONSUMER_SECRET',"");
define('OAUTH_TOKEN',"1U");
define('OAUTH_TOKEN_SECRET',"");
require_once('twitteroauth/twitteroauth.php');
$connection = new TwitterOAuth (CONSUMER_KEY, CONSUMER_SECRET, OAUTH_TOKEN, OAUTH_TOKEN_SECRET);
$connection->post('statuses/update', array('status' => 'testing'));
$httpc = $connection->http_code;
if($httpc == 200) {
echo 'succesvol';
} else {
echo $httpc;
}
You get a 401 (Not Authorised) error when you do not provide the correct ConsumerKey and ConsumerSecret values.
Looking at the code above, you are passing empty string values for those two variables. Unless u left them out on purpose, you need to double check your values.
For my app, this is where they exist.
(ASSUMPTION: you've created a twitter application # dev.twitter.com )
Good Luck!
Related
I'm trying to use Google's API to sign up and log in users to my rails webapp. I've been playing around with the authentication, but I'm getting stuck on this error after I get the authorization code.
Here's what I'm trying to do:
path = Rails.root.to_s + PATH_TO_JSON_FILENAME_FROM_GOOGLE_API
client_secrets = Google::APIClient::ClientSecrets.load(path)
auth_client = client_secrets.to_authorization
auth_client.update!(
:scope => 'https://www.googleapis.com/auth/drive.metadata.readonly',
:redirect_uri => REDIRECT_URI
)
auth_client.code = ACCESS_CODE_RETURNED_BY_GOOGLE_WHEN_USER_LOGS_IN
auth_client.fetch_access_token!
A few questions:
All I really want to be able to pull is the users name, and their email address. I'm unclear on what the proper value for :scope should be.
For the redirect_uri I'm setting it to one of the redirect uri's that are in my Google API console. Something along the lines of http://localhost:3000/auth/callback. Despite this, I'm getting the following json response:
{
"error" : "redirect_uri_mismatch"
}
Thoughts on what I might be doing wrong here?
Finally figured this out. I needed to set the redirect_uri to postmessage, because that's how I originally requested the authorization code. Here's my complete solution:
I load the Google Authentication library with the following:
function start() {
gapi.load('auth2', function() {
auth2 = gapi.auth2.init({
client_id: 'MY_CLIENT_ID',
});
});
};
I created an HTML button, which on click makes the call to the following function:
function(e){
e.preventDefault();
auth2.grantOfflineAccess({'redirect_uri': 'postmessage'}).then(this.signInCallback);
},
Right now the signInCallback function is just logging my authorization code so I can test out the ruby server code I'm writing:
function(authResult) {
console.log(authResult.code);
}
Here's what my ruby file looks like:
client = Google::APIClient.new
client.authorization.client_id = MY_CLIENT_ID
client.authorization.client_secret = MY_CLIENT_SECRET
client.authorization.redirect_uri = "postmessage"
client.authorization.code = CODE_THAT_WAS_LOGGED_TO_CONSOLE
client.authorization.fetch_access_token!
A little more info: you have to use 'postmessage' calling grantOfflineAccess. I tried putting in one of the actual redirect uri's from my developer console, and it didn't like that (see this SO question for more). What I figured out is that if you do this, then you need to do the same thing on the server side when you try to exchange the authorization code for an access token.
Redirect URI mismatch error definitely means that the redirect URI is not the same that is registered. Make extra sure that the URIs are identical.
I have a web based application which use Google OAuth2.0 as the login framework. It works nicely previously until yesterday. The applcation couldn't get the refresh token after the access token expired. Besides that, the "Request for permission" page had change to "Have offline access" instead of "Know who you are on Google" and "View you email"
Originally, the "Request for permission" page will request the access to "Know who you are on Google" and "View you email". After user logout and attempts second login, the "Request for permission" page will be the same too.
However, until yesterday, the "Request for permission" page changed to "Have offline access". After the access token is expired, I got the error messsage below:
PHP Fatal error: Uncaught exception 'Google_AuthException' with message 'The OAuth 2.0 access token has expired, and a refresh token is not available. Refresh tokens are not returned for responses that were auto-approved.' in /home2/xxxx/public_html/test/google-api-php-client/src/auth/Google_OAuth2.php:221
I tried $client->setAccessType('online'); . However, I still got this fatal error with me. Below is my code to get the access token :
if ($client->getAccessToken()) {
$token = $client->getAccessToken();
$authObj = json_decode($token);
$refreshToken = $authObj->refresh_token;
$user = $oauth2->userinfo->get();
$me = $plus->people->get('me');
$email = filter_var($user['email'], FILTER_SANITIZE_EMAIL); // get the USER EMAIL ADDRESS using OAuth2
$optParams = array('maxResults' => 100);
$activities = $plus->activities->listActivities('me', 'public', $optParams);
$_SESSION['access_token'] = $client->getAccessToken();
} else {
$authUrl = $client->createAuthUrl();
}
I tried to search for similar problem like me but I couldn't find one. This happened since yesterday. Before this, I never made any change on the codes.
With his comments, Fabian Parzefall helped me getting this fixed.
Here's my script :
if($client->isAccessTokenExpired()) {
$authUrl = $client->createAuthUrl();
header('Location: ' . filter_var($authUrl, FILTER_SANITIZE_URL));
}
It's actually pretty simple. Instead of asking him to click the "connect me" button (as put by the demo script provided by the GA API team), I redirect him directly.
Not sure if it's the proper/safer way, but that's the one working for me right now!
if($client->isAccessTokenExpired()) {
$client->authenticate();
$NewAccessToken = json_decode($client->getAccessToken());
$client->refreshToken($NewAccessToken->refresh_token);
}
The answer above is 'correct' but I faffed around working out where to put it(!)... so post this for any one else trying out examples that end up with tokens expiring(!).
Once your code has done whatever token stuff it needs, and your client has an access token... then check it is still valid and if not send off for reauthorisation!
// Stuff to do with getting tokens and storing in session etc...
if ($client->getAccessToken()) { // Hey! we got one!
if($client->isAccessTokenExpired()) { // Oh! its not good - go for another
$authUrl = $client->createAuthUrl();
header('Location: ' . filter_var($authUrl, FILTER_SANITIZE_URL));
exit();
}
try{
...
}
Let me explain my question :
In the image we can see a twitter access_token & secret (present on twitter app details page)
when I use the above two and try to update the status it works.
Twitter twitter = TwitterFactory.getSingleton();
twitter.setOAuthConsumer(Tweet.consumer_key, Tweet.consumer_secret);
twitter.setOAuthAccessToken(new AccessToken(u.getTwittertoken(), u.getTwittersecret()));
twitter.updateStatus("test");
But the oauth_token & oauth_secret that I get through using twitter4j callbackURL
don't work with the above code. I always get Invalid/Expired Token error.
I don't know what can be the error. Because it used to work once, but stopped suddenly (don't know exactly when)
Please help! It'll be great if someone can share their code for both - getting & saving the token into database & then getting it again from the db to update the status.
For those who face the same error, here's what I was doing wrong :
I was trying the token & secret received in twitter-response. Although the correct method is to retrieve them from accessToken which has to be retrieved using oauth_verifier being sent in twitter-response.
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setDebugEnabled(true).setOAuthConsumerKey(Tweet.consumer_key);
cb.setOAuthConsumerSecret(Tweet.consumer_secret);
TwitterFactory tf = new TwitterFactory(cb.build());
Twitter twitter = tf.getInstance();
RequestToken requestToken = (RequestToken) mapSession.get("rtoken");
AccessToken accessToken = twitter.getOAuthAccessToken(requestToken, oauth_verifier);
System.out.println("Request Token : " + ToStringBuilder.reflectionToString(requestToken, ToStringStyle.SHORT_PREFIX_STYLE));
System.out.println("Access Token : " + ToStringBuilder.reflectionToString(accessToken, ToStringStyle.SHORT_PREFIX_STYLE));
System.out.println(accessToken.getToken()); //use this further
System.out.println(accessToken.getTokenSecret()); //use this further
I'm trying to get user information from Withings Api, i've already success login into Withings with Oauth using Scribe library(Java). But there is a problem when i sent request to get user information follow Withings Api document it always return result with error code.
I've tried some way but it didn't work. Can someone help me to solve this problem.
Withings Api http://www.withings.com/en/api#documentation
First i call withings action in WithingsController.groovy to get authentication.
After authenticate success server return access token, in withingsCallback action i get user information.
Result return when get user information is result code of Withings Api
{"status":2554}
This is my code
WithingsService.groovy
def getAuthDetails(callbackUrl) {
if (!authService) {
authService = new ServiceBuilder()
.provider(WithingsApi.class)
.apiKey( grailsApplication.config.oauth.withings.key as String )
.apiSecret( grailsApplication.config.oauth.withings.secret as String )
.callback( callbackUrl as String )
.build();
}
Token requestToken = authService.getRequestToken();
[ authUrl : authService.getAuthorizationUrl(requestToken), requestToken : requestToken ]
}
def getWithingsUserInformation(Token accessToken,String userId){
String url = 'http://wbsapi.withings.net/user?action=getbyuserid&userid='+userId;
OAuthRequest request = new OAuthRequest( Verb.POST, url )
authService.signRequest(accessToken, request)
Response response = request.send()
return response
}
def getAccessToken( params, requestToken ){
requestToken = requestToken as Token
Verifier verifier = new Verifier( params.oauth_verifier )
authService.getAccessToken(requestToken, verifier);
}
WithingsController.groovy
def withings() {
def authInfo = withingsService.getAuthDetails(createLink(action: 'withingsCallback', controller: 'withings', absolute: 'true'))
if (authInfo.requestToken)
{
session["withings_requestToken"] = authInfo.requestToken
}
}
def withingsCallback(){
def accessToken = withingsService.getAccessToken(params, session["withings_requestToken"])
session["withings_accessToken"] = accessToken
if(accessToken) {
def profile
String userId = params.userid
profile = withingsService.getWithingsUserInformation(accessToken,userId)
}
}
Unless I'm missing something, it looks like you are not redirecting your user to get the "access token". After you get a request token:
you then generate a authentication url
redirect the user to this authentication url
they will authenticate
if authentication is successful, provider will call your callback with access token
So your withings action should include:
def withings() {
def authInfo = withingsService.getAuthDetails(createLink(action: ....
if (authInfo.requestToken)
{
session["withings_requestToken"] = authInfo.requestToken
}
//are you missing this?
redirect(authInfo.authUrl)
}
If you're using some type of http debugging/logging, check for the following request after your withings action.
https://oauth.withings.com/account/authorize?
oauth_callback=http%3A%2F%2Fexample.com%2Fget_access_token
&oauth_consumer_key=c331c571585e7c518c78656f41582e96fc1c2b926cf77648223dd76424b52b
&oauth_nonce=369f9ceb2f285ac637c9a7e9e98019bd
&oauth_signature=OR9J9iEl%2F2yGOXP2wk5c2%2BWtYvU%3D
&oauth_signature_method=HMAC-SHA1
&oauth_timestamp=1311778988
&oauth_token=5bb105d2292ff43ec9c0f633fee9033045ed4643e9871b80ce586dc1bf945
&oauth_version=1.0
Though this is unrelated to the question initially asked, I thought I would post here since this was a common stopping ground for me reaching a Withings 2554 error.
If updating to the newest version of Withings Api for access token authentication, the current version of the Withings Api will now also cause this 2554 status code if you do not attach action: requesttoken to the access token request body.
Additionally, when pulling apart the response, make sure to drill into the body of the payload, since the latest version of the Withings access token api delivers its payload contents differently. This may be a no brainer for those implementing from scratch, but if you are using an oauth library, most of this behavior is abstracted by the library, and it likely won't be anticipating the payload structure to contain the body field.
more info here: https://developer.withings.com/api-reference#operation/oauth2-getaccesstoken
I'm trying to make authenticated calls to the Bitbucket REST API, with Oauth authentication. I've successfully retrieved an oauth_token and an oauth_token_secret (although they are the same as the request_token and request_token_secret, which seems strange but not outside of the spec). When I make an API call to another endpoint, I get a 401 (not authenticated). I've tried using header authentication and/or passing the oauth_token and oauth_token_secret as HTTP params with the sane result.
Here's the code:
account_name_url = 'https://api.bitbucket.org/1.0/user'
feedback_oauth_hook = OAuthHook(
access_token='REDACTED',
access_token_secret='ALSO_REDACTED',
consumer_key=CLIENT_ID,
consumer_secret=CLIENT_SECRET,
header_auth=True
)
params = {
'access_token': auth_tokens['access_token'],
'access_token_secret': auth_tokens['access_secret']
}
response = requests.get(account_name_url, data=params, hooks={'pre_request': feedback_oauth_hook})
import oauth2 #pip install oauth2
accessToken = oauth2.Token(OAUTH_TOKEN, OAUTH_TOKEN_SECRET)
consumer_key = YOUR_COMSUMER_KEY
consumer_secret = YOUR_CONSUMER_SECRET
consumer = oauth2.Consumer(consumer_key, consumer_secret)
client = oauth2.Client(consumer, accessToken)
api_url = "https://api.bitbucket.org/1.0/user"
resp, content = client.request(api_url, "GET")
print resp, content
The above python code works for me.
I print the request info, notice that it contains oauth_version=1.0 which is required.
I tried removing it, then 401 was returned. I think BitBucket should document this.