Integrate to Bit.ly API Version 4 - How to Generate OAuth2 Token to integrate with Bit.ly API V4 and create a shortened url? - rest

I was having the hardest time trying to generate the OAuth2 token to integrate with the Bitly API v4. Their documentation was hard to comprehend and I couldn't find much online or on StackOverflow on how to accomplish it. I was able to get it to work and wanted to share the solution for anyone else who will be scratching their heads in the future.
Below is a step-by-step guide for Generating Generic Access Token, Retrieving the Group Guid, Generating the OAuth2 token, and calling the Bitly shorten API request.

Bitly API- Steps to get oAuth2 Access token and using the shorten request to retrieve a Tiny Url using Postman:
After spending the better half of a day trying to figure this out I figured I would post this so it could help someone trying to integrate with Bitly API V4.
Note: Bitly API V3 will be deactivated on March 1st, 2020 so be sure to migrate to V4 as soon as possible. All the guids and other private fields in the responses have been altered for privacy.
Click this link to refer to the Bitly API Documentation
1.) Generate Access Token:
Log into bitly.com with your credentials and click on the Hamburger menu in the top right. Click on your Username and then click on the Generic Access Token. This Generic Access token is needed to retrieve your Group Guid. You will need this Group Guid to make the shorten URL Request along with your access token.
2.) Retrieve Group Guid:
Make a GET Request to https://api-ssl.bitly.com/v4/groups to get your group_guid. You will use your Generic Access Token in the Authorization Field.
Below is a picture how the Headers should look:
You should get a JSON Response back that looks similar to the JSON below:
JSON Response of the Retrieve Group Guid GET Response:
{
"groups": [
{
"created": "2019-12-18T13:45:21+0000",
"modified": "2019-12-18T13:45:21+0000",
"bsds": [],
"guid": "XZXUYSJAJ43",
"organization_guid": "JsjFtE841883",
"name": "username",
"is_active": true,
"role": "org-admin",
"references": {
"organization": "https://api-ssl.bitly.com/v4/organizations/JsjFtE841883"
}
}
]
}
Your guid value is your group_guid used in your shorten, and other requests.
3.) Retrieve your client_id and client_secret
Register your application by logging into bitly.com with your user credentials and your application will be assigned a client_id and a client_secret. You can accomplish this by clicking on the Hamburger menu on the right side of the page, click on your username, Registered OAuth Apps, and at the bottom their should be a button that says REGISTER NEW APP.
4.) Generate OAuth2 Access Token
Refer to the Bitly Documentation and under the Authentication tab navigate to "Exchanging a Username and Password for an Access Token".
• Open Postman
• Create a new POST request to https://api-ssl.bitly.com/oauth/access_token.
• Copy the Curl Command but replace username with Bitly Login Username and password with your Bitly Login Password.
• Click on the Import tab and select Past Raw Text and paste over curl command
• In the Authorization tab paste your client_id into the Username field and client_secret into the Password field. This will do the base64encoding for you.
• Your Headers only need the Host and Content-Type key and Value. Your Authorization will be be a temporary header field and will be automatically generated for you.
• Your Body needs:
grant_type: password (the actual word password)
username: your username for bitly.com
password: your password for for bitly.com
Below is a picture of what your Body should look like:
• Click Send and you will receive your access token.
5.) Shorten URL
• Open new tab in Postman and make a Post request to https://api-ssl.bitly.com/v4/shorten
• Headers should include:
• Host: api-ssl.bitly.com
• Authorization: Bearer (your accesstoken from step 4)
• Content-Type: application/json
• Your Body should include this JSON:
{
"long_url": "http://twitter.com",
"group_guid": "guid field from Group Guid Response in Step 2"
}
• Click Send and you should see get a JSON Response like this:
{
"created_at": "2019-12-18T21:50:47+0000",
"id": "yhoo/2PYRS",
"link": "http://yhoo/2PYRS",
"custom_bitlinks": [],
"long_url": "http://yahoo.com/",
"archived": false,
"tags": [],
"deeplinks": [],
"references": {
"group": "https://api-ssl.bitly.com/v4/groups/yourgroupguid"
}
}
The link value in the JSON Response will be your new Tiny URL Link.

Related

"error": "unsupported_grant_type" uber rest api

I am using Uber Rest Api and trying to get access token:
Step 1:
Calling the get web API - https://login.uber.com/oauth/v1.2/authorize?client_id=gdSzxhaqFwjXly338goebrVCh_A7ND8b&response_type=code
Step 2:
URL: https://login.uber.com/oauth/v2/token
Request Body:
{
"client_secret": "xxxxxxxxxxxxxxxxxxxx",
"client_id": "gdSzxhaqFwjXly33",
"grant_type": "client_credentials",
"redirect_uri": "abc",
"code": "EBvazkPeZXbszs4MufjxA0poKUZuur"
}
and getting the response : "error": "unsupported_grant_type"
Please help me to fix the issue.
Thanks
Suresh Patel
First you should double check if you set the correct redirect url in the dashboard - needs to be the same as one on authorization url. Second your request to 'https://login.uber.com/oauth/v2/authorize' seems to contain invalid version. Please follow the steps of the authentication guide.
Briefly, you need to:
• Send user to authorize url. It starts by redirecting the user to the authorize endpoint: https://login.uber.com/oauth/v2/authorize?client_id=YOUR_CLIENT_ID&response_type=code&redirect_uri=YOUR_REDIRECT_URI .You can add scopes as well (check 'scope' parameter on authentication guide)
• Receive the redirect with an authorization code. After the user approves the scopes the user will be redirected to the redirect_uri with an auth code that you can post to the /v2/token endpoint to receive an access token.
• Make a POST call to: 'https://login.uber.com/oauth/v2/token'
• Store access and refresh token for future use
Try making your scope public.
To do that, add:
"scope: "public"
in your param

Non-Google Account Using chrome.identity

I'm trying to make a Gogle Chrome extension that requires user authorization to a SugarCRM 7.5 instance with OAuth 2.0 and I need to store the access token that's retrieved. I may need more clarification on how launchWebAuthFlow works.
Firstly, I can retrieve an access token from SugarCRM by using a POST request (not a GET request) that returns an access and a refresh token.
When I tried using the code below I kept getting the error: "authorization url can not be loaded" and when I checked the background console (I already know that my auth URL is wrong). Any help is appreciated even if you don't know SugarCRM. Just a general answer that can get me started is much appreciated.
manifest.json
{
"name": "Auth Sample",
"version": "1",
"manifest_version": 2,
"minimum_chrome_version": "29",
"key": "<long key>",
"app": {
"background": {
"scripts": ["background.js"]
}
},
"permissions": [
"identity",
"https://<sugar instance>/*"
]
}
Background.js
chrome.identity.launchWebAuthFlow(
{'url': '<url-to-do-auth>', 'interactive': true},
function(redirect_url) { console.log(redirect_url); });
My URL is definitely not gonna work here but it's something like this:
var client_id = '<client id from Oauth 2.0>';
var redirectUri = chrome.identity.getRedirectURL("sugarcrm");
var url = "https://<sugar instance base url>/rest/v10/oauth2/token?client_id=" + client_id + "&callbackURL=" + redirectUri + "&response_type=token"
What's the url-to-do-auth (is this the URL to do a regular login (username and password) to SugarCRM or is it a GET request through the REST API to do login)
I don't have a UI web auth flow for my SugarCRM instance. Is it possible to create one from the application or should that be on the server?
I can only make POST requests to get an access token. Will that still work with launchWebAuthFlow?
Update
I ended up storing the token using the local chrome.storage api and only stored the refresh token which will keep getting a new access token every time the application is run(I think it's more secure than just storing the access token as that will force it to always keep changing without passing other credentials)
After more search on launchWebAuthFlow. I found out that the url launchWebAuthFlow takes as parameter will launch a web page(with interactive parameter set to true) which is hosted on the server, that will let the user login and will return an access token if success. This url is actually an endpoint on the restful server. You need to create this endpoint that will be a get request with some parameters including a callbackURL, client_id and response_type. Then it will respond with another function that will be a post request and will take the username and password. If credentials are correct, it will return the access token as a parameter in the callbackURL(chrome extension specific url that contains the extension ID).
Please feel free to correct me or add something if I'm wrong.

How to verify Facebook access token?

There's only thing that server has to do; just check any access token's validity.
Clients send to the server user id and access token obtained by FB.getLoginStatus. As I expected, there would be any URL that checks access token's validity, like http://xxx.facebook.com/access_token?=xxxxxxxxxxxxxxxxxxxxxxxxxxxx.
That returns whether it's available one or not or is there any API (server side) for that?
The officially supported method for this is:
GET graph.facebook.com/debug_token?
input_token={token-to-inspect}
&access_token={app-token-or-admin-token}
See the check token docs for more information.
An example response is:
{
"data": {
"app_id": 138483919580948,
"application": "Social Cafe",
"expires_at": 1352419328,
"is_valid": true,
"issued_at": 1347235328,
"metadata": {
"sso": "iphone-safari"
},
"scopes": [
"email",
"publish_actions"
],
"user_id": 1207059
}
}
You can simply request https://graph.facebook.com/me?access_token=xxxxxxxxxxxxxxxxx if you get an error, the token is invalid. If you get a JSON object with an id property then it is valid.
Unfortunately this will only tell you if your token is valid, not if it came from your app.
Just wanted to let you know that up until today I was first obtaining an app access token (via GET request to Facebook), and then using the received token as the app-token-or-admin-token in:
GET graph.facebook.com/debug_token?
input_token={token-to-inspect}
&access_token={app-token-or-admin-token}
However, I just realized a better way of doing this (with the added benefit of requiring one less GET request):
GET graph.facebook.com/debug_token?
input_token={token-to-inspect}
&access_token={app_id}|{app_secret}
As described in Facebook's documentation for Access Tokens here.
Simply request (HTTP GET):
https://graph.facebook.com/USER_ID/access_token=xxxxxxxxxxxxxxxxx
That's it.
The app token can be found from this url.
https://developers.facebook.com/tools/accesstoken
I found this official tool from facebook developer page, this page will you following information related to access token - App ID, Type, App-Scoped,User last installed this app via, Issued, Expires, Data Access Expires, Valid, Origin, Scopes.
Just need access token.
https://developers.facebook.com/tools/debug/accesstoken/
Exchange Access Token for Mobile Number and Country Code (Server Side OR Client Side)
You can get the mobile number with your access_token with this API https://graph.accountkit.com/v1.1/me/?access_token=xxxxxxxxxxxx. Maybe, once you have the mobile number and the id, you can work with it to verify the user with your server & database.
xxxxxxxxxx above is the Access Token
Example Response :
{
"id": "61940819992708",
"phone": {
"number": "+91XX82923912",
"country_prefix": "91",
"national_number": "XX82923912"
}
}
Exchange Auth Code for Access Token (Server Side)
If you have an Auth Code instead, you can first get the Access Token with this API - https://graph.accountkit.com/v1.1/access_token?grant_type=authorization_code&code=xxxxxxxxxx&access_token=AA|yyyyyyyyyy|zzzzzzzzzz
xxxxxxxxxx, yyyyyyyyyy and zzzzzzzzzz above are the Auth Code, App ID and App Secret respectively.
Example Response
{
"id": "619XX819992708",
"access_token": "EMAWdcsi711meGS2qQpNk4XBTwUBIDtqYAKoZBbBZAEZCZAXyWVbqvKUyKgDZBniZBFwKVyoVGHXnquCcikBqc9ROF2qAxLRrqBYAvXknwND3dhHU0iLZCRwBNHNlyQZD",
"token_refresh_interval_sec": XX92000
}
Note - This is preferred on the server-side since the API requires the APP Secret which is not meant to be shared for security reasons.
Good Luck.

Get application id from user access token (or verify the source application for a token)

I found this question, which has an answer, but facebook changed the token format since then, now it is something like:
AAACEdEose0cBACgUMGMCRi9qVbqO3u7mdATQzg[more funny letters]ig8b3uss9WrhGZBYjr20rnJu263BAZDZD
In short, you cannot infer anything from it.
I also found the access token debugger, which shows the information I am looking for if you paste a token in, which is nice, but does not help me do it programmatically.
Point is, if someone gets a token for a user, he can use it to access the graph, which is what I do in my application - I want to be sure that people are forwarding the token that was issued to them by my application, and not another.
My application flow is:
Get access token from facebook (nothing special, in the way it is described in here , Server-side Flow. (also iPhone and android and used, but they have similar flows if I recall correctly))
[device] <-> [facebook]
With that access token, the device will access my application server with the token
[device] <-> [Jonathan's application]
At my server I attach the access token to the user and use that to give permissions to that user in my application. (using the facebook connect to authenticate users)
My application is secured, and the access done is also authenticated regardless of facebook, BUT! in this flow, the a weak link I identified is that I cannot authenticate for sure that the access token I got was signed for my application - I do not like it because I cache the tokens for offline use, I want to be 100% sure they are for my application, with my permissions.
So what will be the (best) way to authenticate that the token I got is related to my application (for relation to user, I use the token to access /me and see which user this token is for)
I do not need to decrypt the token (i guess its some sort of AES), I am just looking for an endpoint that will tell me the token matched my application id.
(EDIT: Using the C# SDK, if it matters.. But a graph/rest call to give that info is just as good as well :) )
https://graph.facebook.com/app/?access_token=[user_access_token]
This will return the app this token was generated for, you can compare that against your app's id.
The official graph endpoint for inspecting access tokens is:
GET graph.facebook.com/debug_token?
input_token=[user_access_token]&
access_token=[app_token_or_admin_token]
Example response:
{
"data": {
"app_id": 138483919580948,
"application": "Social Cafe",
"expires_at": 1352419328,
"is_valid": true,
"issued_at": 1347235328,
"metadata": {
"sso": "iphone-safari"
},
"scopes": [
"email",
"publish_actions"
],
"user_id": 1207059
}
}
app_token_or_admin_token can be obtained using the Graph API call:
GET graph.facebook.com/oauth/access_token?
client_id={app-id}
&client_secret={app-secret}
&grant_type=client_credentials
The debug_token endpoint will fail if that user_access_token doesn't belong to the app that generated the app_token_or_admin_token.
Relevant facebook documentation:
Inspecting access tokens:
https://developers.facebook.com/docs/facebook-login/login-flow-for-web-no-jssdk/#checktoken
App Tokens:
https://developers.facebook.com/docs/facebook-login/access-tokens/#apptokens
A documented way to ensure this is to use appsecret_proof.
GET graph.facebook.com/v2.5/me?access_token=[TOKEN]&appsecret_proof=[PROOF]
This verifies not only that it is a valid token, but also that the token belongs to the app. It also gets you user data in one go.
You can derive PROOF above in C# using this (from here):
public static string ComputeHmacSha256Hash(string valueToHash, string key)
{
byte[] keyBytes = Encoding.ASCII.GetBytes(key);
byte[] valueBytes = Encoding.ASCII.GetBytes(valueToHash);
byte[] tokenBytes = new HMACSHA256(keyBytes).ComputeHash(valueBytes);
valueBytes = null;
keyBytes = null;
StringBuilder token = new StringBuilder();
foreach (byte b in tokenBytes)
{
token.AppendFormat("{0:x2}", b);
}
tokenBytes = null;
return token.ToString();
}
ComputeHmacSha256Hash(accessToken, appSecret);
Why not to use official way of doing things? Here's the request from FB's own video about security.
Request:
https://graph.facebook.com/debug_token?input_token={token-to-check}&access_token={app_id}|{app_secret}
Response:
"data": { "app_id": {token-app-id}, "user_id": {token-user-id}, ... }
Link to an official video: https://www.facebook.com/FacebookforDevelopers/videos/10152795636318553/
I made a screenshot so that time is visible, and you can find more info if you are interested.

Facebook access token server-side validation for iPhone app

I'm developing iPhone application, that is based on communication with server, and I want to use Facebook authentication mechanisms.
Basically, I think it should work like this:
In my iPhone app, user logs in to Facebook, using his email and password.
User allows access to his data for related Facebook application.
My iPhone app receives access token, after successful log in.
In further communication with my server, my iPhone application should use the received Facebook access token (for example: in queries).
When my server receives some query from iPhone app, with access token, it should ask Facebook that this token is valid (and for who), and if yes, server should assume that user is authenticated with Facebook.
My question is: how the server should ask Facebook if given access token is valid? I think I should somehow check if the token is valid for my Facebook app.
I've tried many Facebook queries to graph API, that I've found, but nothing worked as I expected. Can you provide me some example?
Here's a two step process you can use to validate that a user access token belongs to your App:
1) Generate an App Access token
(https://developers.facebook.com/docs/howtos/login/login-as-app/)
https://graph.facebook.com/oauth/access_token?
client_id=YOUR_APP_ID
&client_secret=YOUR_APP_SECRET
&grant_type=client_credentials
2) Debug the User Access token
(https://developers.facebook.com/docs/howtos/login/debugging-access-tokens/)
https://graph.facebook.com/debug_token?
input_token=INPUT_TOKEN
&access_token=ACCESS_TOKEN
Where INPUT_TOKEN is the user access token you want to verify, and ACCESS_TOKEN is your app's token that you got from step 1.
The debug endpoint basically dumps all information about a token, so it'll respond with something like this:
{
data: {
app_id: YOUR_APP_ID,
is_valid: true,
metadata: {
sso: "iphone-safari"
},
application: YOUR_APP_NAMESPACE,
user_id: USER_ID,
issued_at: 1366236791,
expires_at: 1371420791,
scopes: [ ]
}
}
If that token isn't from "your app" then it will return an error response.
Update: this answer seems insecure since it doesn't validate the token
first as belonging to your app, see the comments, original answer as
follows:
I assume that you already have the access token in hand. In such a case the simplest way to validate an access token is to issue the following request
https://graph.facebook.com/me?fields=id&access_token=#accesstoken
Here replace #accesstoken with the access token you have. I will breakdown the url and will explain each.
We are issuing a graph api request here which will return the Facebook User Id of the owner of the access token as a JSON string. The keyword 'me' represents the currently logged in user or the owner of the access token. For this request access token is a mandatory parameter.
If the provided access token is not valid or expired Facebook will just return an error message of some sort.
For a valid access token the result will somehow look like this
{
"id": "ID_VALUE"
}
Another solution would be to use https://graph.facebook.com/app/?access_token=[user_access_token] as described by Get application id from user access token (or verify the source application for a token).
This appears to be an undocumented feature, but returns JSON containing the id of the app the token was generated for. If the token wasn't for your app, it returns a 400.
In the latest version of facebook (2.2) you can do it this way:
https://developers.facebook.com/docs/graph-api/reference/v2.2/debug_token
Sample output:
{
"data": {
"app_id": "THE APP ID",
"application": "APP NAME",
"expires_at": 1427245200,
"is_valid": true,
"scopes": [
"public_profile",
"basic_info",
"read_stream",
"email",
"publish_actions",
"read_friendlists",
"user_birthday",
"user_hometown",
"user_location",
"user_likes",
"user_photos",
"user_videos",
"user_friends",
"user_posts"
],
"user_id": "THE USER ID"
}
}
private function facebookRequestMe($access_token)
{
include_once "facebook.php";
$facebook = new Facebook(array(
"appId" => "your_application_id",
"secret" => "your_application_secret"
));
$facebook->setAccessToken($access_token);
return $facebook->api("/me", "GET");
}
You can download the Facebook SDK for PHP from GitHub.
If a user has passed you a Facebook UID that they claim is theirs and you want to check if it's legit, this is a Python function that will verify it against their access token (an implementation of Robin Jome's answer):
def verify_facebook_id(id, access_token):
import requests
import simplejson
params = {'fields': 'id', 'access_token': access_token}
text = requests.get("https://graph.facebook.com/me", params=params).text
json = simplejson.loads(text)
response_id = json["id"]
return response_id == id
This is the only secure method to verify user token using just one request:
https://graph.facebook.com/debug_token?input_token={token-to-inspect}&access_token={app_id}|{app_secret}
Note that a sign "|" in the above URL isn't used as OR but as separator and must be there after fill the other fields.
The response will be JSON looking like that:
{
data: {
app_id: {app_id},
application: {app_name},
expires_at: {some_number},
is_valid: {true|false}
scopes: {array_of_permissions},
user_id: {user_id}
}
}
Reference: https://developers.facebook.com/docs/facebook-login/access-tokens/#apptokens
(above method is mentioned at the bottom of this section)
Along with an access token Facebook also sends an "expires_in" parameter, which is an offset value. Use that to compute for when the access token will expire as an NSDate. Then when you need to do a request compare the current date with the expiration date.
Also try to inspect the status codes and response strings Facebook sends back.