How to get an Instagram Access Token - instagram-api

I'm really struggling in how I'm meant to get my access token for Instagram,
I've registered a new client and then I used this URL
https://api.instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=REDIRECT-URI&response_type=code
to fill in the clients ID and redirect Url.
I then was redirected to a page where it displayed a code in the Url but from there I don't have a clue where id then get my access token.

Link to oficial API documentation is http://instagram.com/developer/authentication/
Longstory short - two steps:
Get CODE
Open https://api.instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=REDIRECT-URI&response_type=code with information from http://instagram.com/developer/clients/manage/
Get access token
curl \-F 'client_id=CLIENT-ID' \
-F 'client_secret=CLIENT-SECRET' \
-F 'grant_type=authorization_code' \
-F 'redirect_uri=YOUR-REDIRECT-URI' \
-F 'code=CODE' \
https://api.instagram.com/oauth/access_token

Almost all of the replies that people have posted so far only cover how to handle access tokens on the front end, following Instagram's client-side "implicit authentication" procedure. This method is less secure and unrecommended according to Instagram's API docs.
Assuming you are using a server, the Instagram docs sort of fail in providing a clear answer about exchanging a code for a token, as they only give an example of a cURL request. Essentially you have to make a POST request to their server with the provided code and all of your app's information, and they will return a user object including user information and the token.
I don't know what language you are writing in, but I solved this in Node.js with the request npm module which you can find here.
I parsed through the url and used this information to send the post request
var code = req.url.split('code=')[1];
request.post(
{ form: { client_id: configAuth.instagramAuth.clientID,
client_secret: configAuth.instagramAuth.clientSecret,
grant_type: 'authorization_code',
redirect_uri: configAuth.instagramAuth.callbackURL,
code: code
},
url: 'https://api.instagram.com/oauth/access_token'
},
function (err, response, body) {
if (err) {
console.log("error in Post", err)
}else{
console.log(JSON.parse(body))
}
}
);
Of course replace the configAuth stuff with your own information. You probably aren't using Node.js, but hopefully this solution will help you translate your own solution into whatever language you are using it in.

I got the same problem before, but I change the url into this
https://api.instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=REDIRECT-URI&response_type=token

The Instagram API is meant for not only you, but for any Instagram user to potentially authenticate with your app. I followed the instructions on the Instagram Dev website. Using the first (Explicit) method, I was able to do this quite easily on the server.
Step 1) Add a link or button to your webpage which a user could click to initiate the authentication process:
Get Started
YOUR_CLIENT_ID and YOUR_REDIRECT_URI will be given to you after you successfully register your app in the Instagram backend, along with YOUR_CLIENT_SECRET used below.
Step 2) At the URI that you defined for your app, which is the same as YOUR_REDIRECT_URI, you need to accept the response from the Instagram server. The Instagram server will feed you back a code variable in the request. Then you need to use this code and other information about your app to make another request directly from your server to obtain the access_token. I did this in python using Django framework, as follows:
direct django to the response function in urls.py:
from django.conf.urls import url
from . import views
app_name = 'main'
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^response/', views.response, name='response'),
]
Here is the response function, handling the request, views.py:
from django.shortcuts import render
import urllib
import urllib2
import json
def response(request):
if 'code' in request.GET:
url = 'https://api.instagram.com/oauth/access_token'
values = {
'client_id':'YOUR_CLIENT_ID',
'client_secret':'YOUR_CLIENT_SECRET',
'redirect_uri':'YOUR_REDIRECT_URI',
'code':request.GET.get('code'),
'grant_type':'authorization_code'
}
data = urllib.urlencode(values)
req = urllib2.Request(url, data)
response = urllib2.urlopen(req)
response_string = response.read()
insta_data = json.loads(response_string)
if 'access_token' in insta_data and 'user' in insta_data:
#authentication success
return render(request, 'main/response.html')
else:
#authentication failure after step 2
return render(request, 'main/auth_error.html')
elif 'error' in req.GET:
#authentication failure after step 1
return render(request, 'main/auth_error.html')
This is just one way, but the process should be almost identical in PHP or any other server-side language.

The easy way that works in 2019
Disable implicit oauth under the security auth and THEN load this:
https://api.instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=REDIRECT-URI&response_type=token
Specify REDIRECT-URI in your account and type it exactly as specified.

The access token is returned as a URI fragment after you authorize the application to use your Instagram data. It should look something like the following:

Try this:
http://dmolsen.com/2013/04/05/generating-access-tokens-for-instagram/
after getting the code you can do something like:
curl -F 'client_id=[your_client_id]' -F 'client_secret=[your_secret_key]' -F 'grant_type=authorization_code' -F 'redirect_uri=[redirect_url]' -F 'code=[code]' https://api.instagram.com/oauth/access_token

100% working this code
<a id="button" class="instagram-token-button" href="https://api.instagram.com/oauth/authorize/?client_id=CLIENT_ID&redirect_uri=REDIRECT_URL&response_type=code">Click here to get your Instagram Access Token and User ID</a>
<?PHP
if (isset($_GET['code'])) {
$code = $_GET['code'];
$client_id='< YOUR CLIENT ID >';
$redirect_uri='< YOUR REDIRECT URL >';
$client_secret='< YOUR CLIENT SECRET >';
$url='https://api.instagram.com/oauth/access_token';
$request_fields = array(
'client_id' => $client_id,
'client_secret' => $client_secret,
'grant_type' => 'authorization_code',
'redirect_uri' => $redirect_uri,
'code' => $code
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
$request_fields = http_build_query($request_fields);
curl_setopt($ch, CURLOPT_POSTFIELDS, $request_fields);
$results = curl_exec($ch);
$results = json_decode($results,true);
$access_token = $results['access_token'];
echo $access_token;
exit();
}
?>

This worked just fine for me:
http://jelled.com/instagram/access-token
FYI, I used it in combination with the jQuery Instagram plugin which you'll find here;
http://potomak.github.com/jquery-instagram

If you're looking for instructions, check out this article post. And if you're using C# ASP.NET, have a look at this repo.

By using https://www.hurl.it/ i was able to see this:
{
"code": 400,
"error_type": "OAuthException",
"error_message": "Matching code was not found or was already used."
}
so: you have to get new code for every request.

If you don't want to build your server side, like only developing on a client side (web app or a mobile app) , you could choose an Implicit Authentication .
As the document saying , first make a https request with
https://api.instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=REDIRECT-URI&response_type=token
Fill in your CLIENT-ID and REDIRECT-URL you designated.
Then that's going to the log in page , but the most important thing
is how to get the access token after the user correctly logging in.
After the user click the log in button with both correct account and password,
the web page will redirect to the url you designated followed by a new access token.
http://your-redirect-uri#access_token=ACCESS-TOKEN
I'm not familiar with javascript , but in Android studio ,
that's an easy way to add a listener which listen to the event the web page override the url to the new url (redirect event) ,
then it will pass the redirect url string to you , so you can easily split it to get the access-token like:
String access_token = url.split("=")[1];
Means to break the url into the string array in each "=" character , then the access token obviously exists at [1].

go to manage clinet page in :
http://www.instagram.com/developer/
set a redirect url
then :
use this code to get access token :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>tst</title>
<script src="../jq.js"></script>
<script type="text/javascript">
$.ajax({
type: 'GET',
url: 'https://api.instagram.com/oauth/authorize/?client_id=CLIENT-‌​ID&redirect_uri=REDI‌RECT-URI&response_ty‌pe=code'
dataType: 'jsonp'}).done(function(response){
var access = window.location.hash.substring(14);
//you have access token in access var
});
</script>
</head>
<body>
</body>
</html>

Related

React Native Expo Cli Facebook Authentication - unable to exchange Response type code for access token on server API

I am creating React Native app using Expo and used its inbuilt Facebook.useAuthRequest to generate a response when a user logs in. When I create a response type of Token I am able to take this token and send it to my backend API that successfully uses it to get the user details.
However I had hoped to implement a response type of code and use this on the backend API generate the access Token and then request the user details - as I believe this is the most secure option when sending the code to my server.
The issue that I'm facing is that I keep getting an error when trying to formulate the requst to Graph API and I dont understand why:
error: {
message: 'Missing client_id parameter.',
type: 'OAuthException',
code: 101,
fbtrace_id: 'ARHcoh260kBwj7l9yDHjU-n'
}
I just want to confirm that I believe I have inserted all the correct information into the request, so I am unsure of why this error is saying its missing the cliend_id. Here is my request from my API server:
const { data } = await axios({
url: https://graph.facebook.com/v12.0/oauth/access_token? client_id=${appId} &redirect_uri=${redirectUri} &client_secret=${appSecret} &code=${code},
method: 'get',
});
I just want to confirm that the client_id I have taken from app id I created on the facebook developer page, as well as the client_secret, redirect is the https:// used in the initial request and the code is the code initially received in my client side request.
Thanks in advance for any suggestions :)
Just a quick update on this, I was ablel to reformat the request as I believe it had some errors in the spacing and I moved to using the .env files so now my request looks like this:
const redirectUri = {MY_REDIRECT URL};
const appId = process.env.FACEBOOK_CLIENT_ID;
const appSecret = process.env.FACEBOOK_CLIENT_SECRET;
const { data } = await axios({
url: `https://graph.facebook.com/v12.0/oauth/access_token?client_id=${appId}&redirect_uri=${redirectUri}&client_secret=${appSecret}&code=${code}`,
method: 'get',
});
It seems I have moved onto a new error with the following:
error: {
message: 'Invalid code verifier. Code verifier should be a cryptographically random string using the characters A-Z, a-z, 0-9, and the punctuation characters -._~ (hyphen, period, underscore, and tilde), between 43 and 128 characters long.',
type: 'OAuthException',
code: 1,
fbtrace_id: 'AQKIUad5RRCitb6m977fnFW'
}
I'm a bit stumped for what this means as I have checked and all my values appear correct. My only thought is if I need to do something with the code initially received on the client side?
Ok so I finally figures it out - the issue was the I wasn't sending the code_verifier along with my request to exchange the Auth Code for a token. I ended up sending this code_verifier to my API server then adding this to the request so it looked something like this:
FB.api(
'oauth/access_token',
{
client_id: appId,
client_secret: appSecret,
redirect_uri: redirectUri,
code_verifier: code_verifier,
code: code,
},
function (response) {
if (!response || response.error) {
console.log(!response ? 'error occurred' : response.error);
return;
}
var accessToken = response.access_token;
This then finally gave me the accessToken I was looking for that I can then use to exchange for user details server side.
... and the code_verifier is obtained from request.codeVerifier.
const [request, response, promptAsync] = Facebook.useAuthRequest(...

Unable to post comments to a Pull Request using Github API

I am using GitHub API to create comments to Pull Requests.
Following this:
I do not want to comment to specific line of code, rather a general comment to the PR itself. Say for example "Thanks for your PR #author"
// Using Joomla Http library that uses cURL internally
$http = new HttpRequest;
// The url variables below are set to the respective correct values
$url = "https://api.github.com/repos/{$owner}/{$repo}/issues/{$number}/comments";
// Method: post($url, $data, $headers);
$resp = $http->post($url, array('body' => 'Thanks for your PR #author'), array('Authorization' => 'token ' . PERSONAL_ACCESS_TOKEN));
This returns the following error:
{
"message": "Invalid request.\n\nFor 'links/0/schema', nil is not an object.",
"documentation_url": "https://developer.github.com/v3/issues/comments/#create-a-comment"
}
What I read in the docs, links is nowhere mentioned as a parameter for this request, so this is confusing me more.
PS: All other operations such as get reviews list, get comments list, delete a comment, add a label to PR, remove a label from PR etc. are working fine.
I found somewhere they say some additional authentication is required for commenting. I am not sure what that exactly mean and how I achieve that.
I have only Personal Access Token to validate my requests.
Please advise what I am missing.
I was able to post the comment using issues api instead of pull-request
public function comment($message)
{
$http = new HttpRequest;
$url = "https://api.github.com/repos/{$this->owner}/{$this->repo}/issues/{$this->num}/comments";
$headers = array(
'Content-Type' => 'application/json;charset=utf-8',
'Authorization' => 'token ' . GITHUB_ACCESS_TOKEN,
);
$resp = $http->post($url, json_encode(array('body' => $message)), $headers);
return $resp->code == 201 ? $resp : null;
}
The HttpRequest class in part of an internal library which is not much important here. You should be able to use any Http transport method.
Only important things are the request url, headers and request data.
Make sure the ACCESS_TOKEN in use is assigned the correct permissions. I can't remember it for now, will add here when I get a chance to look at it.

How to call Management API v2 to send verification mail from within a rule?

I'm writing a rule in Auth0 to trigger a verification email if a certain condition is met. To make the example small I have included the code which I am using to send the verification mail (I have removed out the unwanted code).
var url = 'https://myname.au.auth0.com/api/v2/jobs/verification-email';
var token = 'Bearer {{token}}'; //This is where the problem is how do I get the token
var userId = user.user_id;
request.post({
url: url,
headers: {
Authorization: 'Bearer {{token}}',
},
json: {
"user_id": user.user_ID
},
timeout: 5000
},
function(err, res, body) {
console.log(err);
console.log(res);
});
In the body I get the following error
{ statusCode: 400,
error: 'Bad Request',
message: 'Bad HTTP authentication header format',
errorCode: 'Bearer' }
I guess I need to pass in the access token or something like that in the header. How do I get this done?
I also saw the following article (https://auth0.com/docs/email/custom), however I'm not sure what secretToken is?
Starting from the bottom, the article (https://auth0.com/docs/email/custom) is aimed at users that want additional flexibility and use their own custom email handling. The secretToken on that example it's just to illustrate a possible - and very simple - way that their own custom email API could validate that they were being called from Auth0; in conclusion it would work almost as an API key.
If you only need to trigger a verification email through the system provided by Auth0 you're using the correct approach (Management API v2). You have more than one way to obtain a token that allows you to call this API:
Using the client credentials grant
Using the Auth0 Management API v2 Explorer
The second option would be the easiest to get started, but do take in consideration that there's a deprecation notice for that one.
Once you obtain the token, you also need to correctly pass it to the API. The code you showed may be only sample code, but make sure that you don't end up including the Bearer scheme twice, more specifically var token = 'Bearer {{token}}'; should instead just be var token = '{{token}}'; and then you would use the token variable when creating the HTTP header.
Just created the below empty rule that will get called when user tries to login and email is not yet verified and it works like a charm :D
function (user, context, callback) {
if (!user.email_verified) {
console.log("User is: " + user.user_id);
var ManagementClient = require('auth0#2.6.0').ManagementClient;
var management = new ManagementClient({
token: auth0.accessToken,
domain: auth0.domain
});
var new_userobj = {user_id:user.user_id};
management.sendEmailVerification(new_userobj,callback(new UnauthorizedError('Please click on the link in the email we have sent you to continue to login.')));
} else {
return callback(null, user, context);
}
}
I received the same error when using the wrong token, though for a different api call. I recreated your issue by using a user's access_token obtained by calling {{api-audience}}users/{{user_id}}. That token should look something like this: A1bCd2efg34IJkl5
Try using a client's access_token obtained by making this call:
curl --request POST \
--url https://{{domain}}/oauth/token \
--header 'content-type: application/json' \
--data '{
"client_id":"{{client_id}}",
"client_secret":"{{client_secret}}",
"audience":"{{audience}}",
"grant_type":"client_credentials"
}'
That token will be a full JWT.

How to send the JWT token to the client with feathersjs-authentication?

I'm using local authentication in my feathersjs REST-API application, but after the user is authenticated, instead of sending me the authentication token, feathers is sending the following HTML as a response to the authentication request:
<body>
<img class="logo" src="alongbase64string" alt="Feathers Logo">
<main>
<h1 class="center-text">Success</h1>
<h3 class="center-text">You are now logged in. We've stored your JWT in a cookie with the name
<span class="italic">"feathers-jwt"</span> for you. It is:
</h3>
<pre id="token"></pre>
</main>
<script type="text/javascript">
function getCookie(name) {
var value = "; " + document.cookie;
var parts = value.split("; " + name + "=");
if (parts.length == 2) return parts.pop().split(";").shift();
}
var token = getCookie('feathers-jwt');
var el = document.getElementById('token');
el.innerHTML = token;
</script>
which prints the following page:
I think this would work good enough if I was sending the request from a web page, but in my case I need to get the token, because the client is a mobile app, not a web browser, so cookies won't work for me.
Is it possible for me to make feathersjs send the token in the response? Something like:
{
token: 'açldkjfaçldkfjçasdkfjdçakfjd'
}
This way I could store the token in the mobile app, and use it to authenticate further requests to my feathersjs API server.
For now I won't put any more code here, because the application was made entirely with the console commands available by feathersjs, like feathers generate but if anyone needs to understand more about the code, just let me know, and I will edit the question adding more details.
You have to make sure to set the Accept header in your request to application/json otherwise it'll assume HTML and send the page you are seeing.
Use the local middleware instead of the socket scheme referenced in the question.
POST'ing login data to /auth/local will yield
{
"token": {JWT},
"data": {
"email": "admin#feathersjs.com",
"id": 0
}
}
Your client can pull values from that JSON response and handle them appropriately.
Most anything beyond that will require modifying the stock Feathers demo.

Performing simple authentication in Angular and Node

I have been struggling with performing simple authentication in my angular node application. I am well aware that there are ready to use angular-express yeoman kits out there. But I want to understand this fuly and hence the attempt.
What I have been able to do so far is create a login form which connects to node server. It sens login name and password and receives a response back.
Where I am stuck is how to convert this simple interaction into a authentication process.
My Directory structure is as below
--ParentDirectory/
-client/
--css/
--lib/ /*all angular and jquery library files*/
--src/ /* All other angular modules, directives etc */
--app.js
--index.html /* default page associated with app.js
--login.js /*module login is independent of app.js module */
--login.html
-server/
--server.js /*restify code sits here */
app.js is where the main app resides.
So far it looks like :
angular.module('app',['']);
angular.module('app').controller('mainCtrl',function($scope){
$scope.hello = "Hello World";
});
Now First things first.. when a user visits my website i.e index.html page.. they will end up in this app and I would like for them to be re-directed to login.html page if they are not authenticated.
Any clues on how to achieve that ?
Moving on..
Login.html simply asks for a username and password (not showing the code here to keep things compact)
Login.js looks like this:
angular.module('loginApp',['common.webservice'])
.controller('loginCtrl',['$scope','WSLogin','$location','$window','Authen',function($scope,WSLogin,$location,$window,Authen){
$scope.message;
$scope.submit = function(){
var temp = {logonID: $scope.username,password: $scope.password};
WSLogin.save(temp,function(result){
Authen.isLogged = true;
$window.sessionStorage.token = result.token;
$scope.message = result.token;
$location.path("/main");
},function(err){
$scope.message = "Authentication failed. Pls retry";
});
};
$scope.logout = function(){
if (AuthenticationService.isLogged){
Authen.isLogged = false;
delete $window.sessionStorage.token;
$location.path("/");
}
}
}])
.factory('Authen', function() {
var auth = { isLogged :false };
return auth;
});
WSLogin is a resource that connects to the node serve on the path user/authenticate. This webservice is working fine so far.
[not showing the code here to keep things compact]
The server.js file looks like this:
var restify = require('restify');
var server = restify.createServer({
log: log,
name: 'demo'
});
server.listen(12345, function(){
console.log('%s listening at %s', server.name,server.url);
});
server.post('/user/authenticate',function(req,res,next){
if (!(req.params.logonID === "test" && req.params.password === "test")) {
res.send(401, 'Wrong user or password');
return;
}
var profile = {
first_name: 'John',
last_name: 'Doe',
email: 'john#doe.com',
id: 123
};
// we are sending the profile inside the token
res.json({token:profile);
});
How can I patch things up so that this somewhat resembles a authentication system.
I have picked up tips from various blogs, sites etc.. but no luck implementing them.
I understand you want to know how things are built, but I highly recommend picking up Passport to use on the Node/server side for authentication. With that said, in your implementation of login, it might be easier to include a cookie with the token in the response, rather than returning the token in the response. The code can then return a 200 (or 201) response code to indicate the login was successful, but by moving the token to a cookie, the client code doesn't have to deal with sending the token on future requests -- it's sent automatically in a cookie.
Moving on to your client side questions, keep in mind that you would enable security to protect resources on the server side. Anything you put in your client side JavaScript code can be read by anyone. So in the end these APIs that return protected data are the ones that need to be protected. Again, Passport provides an easy way to protect an API, but you could validate that each API request contains this token (or cookie) prior to providing the data.
In the case that the request is not authorized (it doesn't contain the token, or the token is invalid), you can return a 401 (Unauthorized) response. In the client side code, you can check for this and automatically route the user to the Login page.
Using Angular, one pattern to accomplish this is to use httpProvider Interceptors which allow you to hook into each HTTP request. You could check for a responseError with a status of 401, and route them to the Login page.

Resources