Angular.js 401 Unauthorized Status Code - angularjs

I want to get access token for authentication. My post result like
POST https://staj-io-goldenilkay92-1.c9.io/api/v1/oauth/token 401 (Unauthorized)
but when I try to post with postman it works.
Server Side Headers
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type, Authorization');
res.setHeader('Access-Control-Allow-Credentials', 'true');
res.header('Content-Type', 'application/json');
Angular Code
Service
function signIn(data) {
var deferred = $q.defer();
$http.post('https://staj-io-goldenilkay92-1.c9.io/api/v1/oauth/token', data,
{headers: {'Content-Type': 'application/x-www-form-urlencoded'}}
)
.success(function (response, status, headers, config) {
deferred.resolve(response);
}).error(function () {
deferred.reject("Failed to login");
});
return deferred.promise;
}
controller
vm.loginData = {
'client_id': 'client',
'client_secret': 'client',
'grant_type': 'password',
'username': '',
'password': ''
};
vm.login = function login() {
loginService.signIn(vm.loginData).then(function (result) {
vm.signInResult = result;
},
function (data) {
});
}
POST https://staj-io-goldenilkay92-1.c9.io/api/v1/oauth/token 401 (Unauthorized)

Here is suggestions to solve your problem;
Use cors module (not required);
Server Side
I assume that your passport code working properly.
var cors= require('cors');
//init first.
app.options(cors({origin'*'})); //Use your origins.
app.use(cors({origin'*'})); //Use your origins.
Client Side
Just delete headers options
//...
$http.post('https://staj-io-goldenilkay92-1.c9.io/api/v1/oauth/token', data)
.success(function (response, status, headers, config) {
deferred.resolve(response);
}).error(function () {
deferred.reject("Failed to login");
});
//...

If one POST works and the other doesn't, then your angularjs $http request is making the request with the wrong parameters.
I'd suggest you to get an http analyser (like Fiddler) and compare the actual request done by Postman vs the request done by you angular app.

Related

POST, PUT, DELETE requests from AngularJS $http/AJAX to Node.js + Express.js based API

I wrote backend API on Node.js and Express.js v4, this part (index.js):
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', 'http://example.com');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
app.post('/add1', function (req, res) {
db.one("INSERT INTO table(value1) VALUES (${value1}) RETURNING ID", req.query).then(function (data) {
res.json(data);
}).catch(function (error) {
res.json(error);
});
});
app.put('/add2', function (req, res) {
db.one("INSERT INTO table(value1) VALUES (${value1}) RETURNING ID", req.query).then(function (data) {
res.json(data);
}).catch(function (error) {
res.json(error);
});
});
app.get('/add3', function (req, res) {
db.one("INSERT INTO table(value1) VALUES (${value1}) RETURNING ID", req.query).then(function (data) {
res.json(data);
}).catch(function (error) {
res.json(error);
});
});
And I have Angular JS or sample ajax like this
app.controller('globalController', function($scope, $http) {
var jsd = {};
jsd.value1=1;
$http.put(API_URL + 'add2', jsd).then(function(data) {
console.log(data);
}, function(data) {
console.log(data);
});
});
and
$.ajax({
url: API_URL + 'add1',
method: 'POST',
dataType: 'json',
data: jsond,
success: function(data) {
console.log(data);
},
error: function(data) {
console.log(data);
}
});
But I don't recive any data to my req.query and in generally in req object. When I make my AJAX request to add3 with get, then all works, req.query has my params.
I read about this solution:
app.config(function ($httpProvider) {
$httpProvider.defaults.transformRequest = function(data){
if (data === undefined) {
return data;
}
return $.param(data);
};
$httpProvider.defaults.headers.put['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
});
and solution here
var multer = require("multer");
//...
var upload = multer({ dest: "./upload/" });
app.post("/post", upload.array(), function(req, res) {
console.log(req.body);
res.send(null);
}
I tried first, not works, and second is too strange solution (I can't save data to files and etc.) I think problem was in fist OPTION request, but I googled it, not found solution. I need little example (working code) how I can send POST or PUT data from Angular $http or AJAX and use this data in req object in node.js. In GET requests all this works, but how I can make it work on others?
Which version of Express are you using? It's possible that you're writing the old way and using the new version.
You might wanna check this out -- How to retrieve POST query parameters?
Anyway, I'd suggest you use ngResource for making REST HTTP calls in Angular.
Instantiate the Factory
This will expose a few methods e.g query, save etc.
angular
.module('MyModule')
.factory('AddEndpoint', AddEndpoint);
AddEndpoint.$inject = ['$resource'];
function AddEndpoint($resource) {
return $resource(API_URL + '/:param', { param: '#param' });
}
Enjoy The Factory
angular
.module('MyModule')
.controller('MyController', MyCtrl)
MyCtrl.$inject = ['AddEndpoint'];
function MyCtrl(AddEndpoint) {
var scope = this;
scope.getFromApi = AddEndpoint.get({ params: 'add1' }); // GET 'API_URL/add1'
scope.postToApi = postToApi;
function postToApi(data) {
data.params: 'add2'
AddEndpoint.save(data); // POST to 'API_URL/add2'
}
}

$http get dosn't work frome code but works with other rest client

I have a problem with angular $http get with Authorization header.
I tried to excute the same request with different rest client and response are the same each one.
Advanced Rest Client Chrome extension
Soap-Ui
Insomnia
I have always received the same response with 200 status code.
but when I try to make the same call from my angular application I get 403 status code and response is an OPTIONS.
where I'm wrong?
this is my code:
Config
app.config(function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
$httpProvider.defaults.headers.common['Authorization']='Bearer 24ac24e6-0f9b-48b5-923f-b75986226bd9';
});
Service
app.service('DiscoveryService', function ($http) {
this.getData = function (callbackFunc) {
$http({
url: 'https://test.test/test-api/source-monitor/v1/discover',
method: 'GET',
headers: {
"Content-Type": "application/json"
}
}).success(function (response) {
console.log(response);
}).error(function (error) {
console.log(response);
});
};
});
Controller
DiscoveryService.getData(function (dataResponse) {
$scope.data = dataResponse;
});

Response for preflight has invalid HTTP status code 404 in AngularJS

I am trying to use Angular's POST and PUT methods but I keep getting the error:
Response for preflight has invalid HTTP status code 404
My code:
$http({
method: "POST",
url: "http://localhost:4567/api/v1/project",
data: project_data
}).then(function successCallback(response) {
console.log(response);
}),
function errorCallback(response) {
console.log('error!');
console.log(response);
}
$http({
method: "PUT",
url: "http://localhost:4567/api/v1/project/1",
data: data
}).then(function successCallback(response) {
console.log(response);
}),
function errorCallback(response) {
console.log('error!');
console.log(response);
}
Does anyone know what might be going on or how to fix it? Other solutions I've found involve changes to the server side code (in this instance, I don't have access to the server). Thanks in advance!
If you use Node.js, just do this:
app.options('/api/v1/project/1', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Content-Type, Content-Length, Authorization, Accept,X-Requested-With");
res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
res.header("Content-Type", "application/json;charset=utf-8");
res.status(204);//important
res.end()
});
app.put('/api/v1/project/1', function(req, res, next) {
...your normal code here
})

how to pass headers in http call in angularjs

I am developing mobile application in cordova/phonegap. I am using angularJS for front-end. I am calling services which required 'API-KEY' attribute as header in post request.
I show some documentations, and tried with those way. but not worked.
postServiceDataWithHeader: function (url, data) {
var deferred = $q.defer();
var req = {
method: 'POST',
url: url,
data: JSON.stringify(data),
headers: {
'user-Token': $rootScope.user.APIKEY,
'content-Type': 'Application/Json'
}
}
$http(req).success(function (data) {
deferred.resolve(data);
}).error(function (data, status, headers, config) {
alert("Server failed to save data");
deferred.reject(status);
});
return deferred.promise;
}
I tried to add headers in call with,
JodoModule.config(function ($routeProvider, $httpProvider) {
$httpProvider.defaults.headers.post['user-Token'] = 'finding???';
$httpProvider.defaults.headers.post['Content-Type'] = 'application/json; charset=utf-8';
});
and second approach was,
JodoModule.run(['$rootScope', '$http', function ($rootScope, $http) {
$http.defaults.headers.common.Authorization = 'Basic YmVlcDpib29w';
}]);
I am able to call services, but on server side, I am not getting header values, even in fiddler also headers are not passed.
What is the reason ? Do I need to add anything else in code for passing headers for each POST request. ?
I've made working plunker for you using one of yours approach
http://plnkr.co/edit/36Dq6UXgyeMEXOzycrua?p=preview
app.config(function ( $httpProvider) {
$httpProvider.defaults.headers.post['User-Token'] = 'finding???';
$httpProvider.defaults.headers.post['Content-Type'] = 'application/json; charset=utf-8';
});
Although if it's CORS you have to add 'User-Token' to accepted headers
i.e. for apache2
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Headers "origin, user-token, x-requested-with, content-type"
Header set Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"

CORS error with Facebook callback function

I have the following code:
app.js:
var passport = require('passport')
, FacebookStrategy = require('passport-facebook').Strategy
, ...
passport.serializeUser(function(user, done) {
console.log('serializing user')
done(null, user);
})
passport.deserializeUser(function(obj, done) {
console.log('deserializeUser')
done(null, obj)
})
passport.use(new FacebookStrategy({
clientID: FBAPP.id,
clientSecret: FBAPP.secret,
callbackURL:
"http://www.mylocal.com:3000/auth/facebook/callback"
},
function(accessToken, refreshToken, profile, done) {
// asynchronous verification, for effect...
process.nextTick(function () {
return done(null, profile)
})
}
))
app.get('/auth/facebook', passport.authenticate('facebook',
{ scope: ['email, user_likes, user_photos, publish_actions'] }))
app.get('/auth/facebook/callback',
passport.authenticate('facebook', {
successRedirect: '/loginsuccess', failureRedirect : '/loginfail' }))
app.get('loginsuccess', function(req, res) {
console.log('Login success')
res.send(200, 'ok')
})
app.get('/loginfail', function(req, res) {
console.log('Login error')
res.send(401, 'error')
})
The angular part:
factory('FacebookFactory', ['$http', '$q', function($http, $q) {
var get = function() {
var deferred = $q.defer();
$http({method: 'GET', url: '/auth/facebook'}).
success(function(data, status, headers, config) {
deferred.resolve(data);
}).
error(function(data, status, headers, config) {
deferred.reject(data);
});
return deferred.promise;
};
return {
get: get
};
}])
I get always this error and did several attempts but no success.
XMLHttpRequest cannot load https://www.facebook.com/dialog/oauth?
response_type=code&redirect_uri=http%…
user_likes%2C%20user_photos%2C%20publish_actions&client_id=xxxxxxxxxxx.
No 'Access-Control-Allow-Origin' header
is present on the requested resource. Origin '[basic
links]http://www.mylocal.com:3000' is therefore
not allowed access.
Anyone any idea? I did try it solely in angular but then it does not work in Safari but in Chrome and FF it works perfectly.
www.mylocal.com:3000 = localhost:3000
You will not find a solution with client side languages as this constitutes a cross-origin request which could be used as a malicious attack. So basically the Facebook endpoint would need to have a Access-Control-Allow-Origin header block set and I don't think they will do that anytime soon. I use APIs alot and frequently have to have theses headers set in my endpoint so my clients can connect from localhost or dev urls:
if (isset($_SERVER['HTTP_ORIGIN'])):
header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 86400');
endif;
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS'):
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'])):
header('Access-Control-Allow-Methods: GET, POST, OPTIONS, DELETE, PUT');
endif;
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])):
header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
endif;
exit(0);
endif;
You could also try this in your $http broker:
var promise = $http({
method: 'POST',
url: 'url_to_api',
data: params,
headers: {
'Access-Control-Allow-Origin': true,
'Content-Type': 'application/json'
}
}).success(function (data, status, headers, config) {
return data;
});
I have an Angular app with express on the backend. When I clicked on a button with this HTML:
<input type="button" ng-click="socialLogIn('facebook')" class="modal-input" value="Sign in with Facebook">
It gave me a CORS error:
$scope.socialLogIn = function (social) {
return $http.get ('/auth/'+social).success (function (data) {
auth.saveToken (data.token); // write data to local storage
});
Problem is, I wanted to get the token back so I could save it in localStorage. I did solve it, but the solution is round-about. In the socialLogIn function, I opened a new window:
$scope.socialLogIn = function (social) {
var url = 'http://' + $window.location.host + '/auth/' + social;
$window.open(url);
};
In the express backend, after I got my 'stuff' from Facebook or Google and I created the token, I sent back some code that saved the token, reloaded the parent window and closed itself:
function loginReturn (res, token) {
var returnString = '' +
'<!DOCTYPE html>\n' +
'<html>\n' +
'<head>\n' +
'<meta charset="UTF-8">\n' +
'<title>Login</title>\n' +
'</head>\n' +
'<body>\n' +
'<script type="text/javascript">\n' +
'window.localStorage[\'token\'] = \''+token+'\';\n' +
'window.opener.location.reload(false);\n' +
'window.close();\n' +
'</script>\n' +
'</body>\n' +
'</html>';
res.send(returnString);
};

Resources