angular ngresource can't send headers - angularjs

I'm new to the angularjs/ionic mobile app development. I'm using Parse REST api to store data and already hosted Parse server in Heroku. Tested with postman chrome extension and everything working fine. The problem that i'm facing right now is my angular-resource seem look like not sending any headers used to authenticate with parse to the server.
angular.module('starter.services', ['ngResource']).factory('Session', function ($resource) {
return $resource('/restapiurl', {}, {
get: {
method:'GET',
headers:{'X-Parse-Application-Id':'XXX', 'X-Parse-REST-API-Key':'XXX'}
}
});
});
Need an advice/guide to make my code work perfectly. Any help would be appreciate. Thanks in advance
UPDATE: I'm managed to send custom headers to the server. The workaround is to use $httpProvider.defaults.headers.common with the key and value inside module.config

Related

AngularJs + Django RESTful: session based authentication

I'm developing an angular web application that will replace the current website that we have. The current website uses session based authentication. At the moment, I can't access the hosted API with get or post requests.
I'm developing the angular application on my local computer using a python simple server, whereas the api is hosted online.
I would prefer to find a fix that's completely in angular since I can't change the API without help (it was written by my boss a while ago, and is now used in the production version). I don't have a login page so I'm just trying to provide the authentication information in my headers and requests.
My angular application was written independent of django. I just want to access the django backend
So far I'm trying the following to set the headers:
app.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
$httpProvider.defaults.headers.common = {'username': btoa('myUsername'), 'password': btoa('myPassword')
};
}]);
And in my service:
app.factory('Test', ['$resource', function($resource) {
return $resource('https://www.phonywebsite.org/en/api/test/')
};
I consistently get 301, 400 and 403 errors. Lately it's been mostly 301 errors and I get no response from the api. I'm using the Allow CORS chrome extension as a temporary fix to try to get to the api without getting a CORS policy error.
My questions
How can I fix the CORS errors without using the chrome extension?
How do I provide my authentication to my django backend that uses session based authentication making sure the csrf cookie its looking for is in the header?
To answer your first question, using the cors extension is a temporary solution and should mostly never be used cause your clients might not use it. To handle CORS, you need to understand how cross site API calls work. In short CORS is a mechanism that allows AJAX requests to circumvent their same origin limits. To handle such situations you need to update your backend and add
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True
. Once you add this your settings.py should stop getting CORS issues.
To answer your second question, angular already provides you with support for CSRF so half of your battle is already won. What you need to do is add a patch on your module to start accepting csrf tokens (The name is a bit different in angular). You have already done this and done a good job of it as well:
var app = angular.module('app', ['...']);
app.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
}]);
What this would do is make sure that whenever you make a $http call your csrf token is set as well.
As a learning oppurtunity, you could also try using ng-cookies as well. To go further to explain this, whenever you make a call in angular , your request in bundled with cookies as well so you can easily access them in request.COOKIES.
You need to change how you are calling your API as well, something like:
app.factory('APIService', function ($http) {
return $http({url: 'https://www.phonywebsite.org/en/api/test/',
method: 'GET'})
}
You can obviously make modifications to this but I think this shows the $http usage to make you understand the general gist.
You can try to add some more authentication around your application here as well (or replace django auth with your own custom auth), but that is on your use case.
Hope this helps.

How to authenticate application while making AJAX calls?

I have the following Code in AngularJs, but , how can I ensure that I am sending the authenticated app to communicate to back end?
resp.get
Update = function () {
//return $http.get(urlBase);
return $http({
method: 'GET',
url: urlBase + eventList,
});
};
e.g.:
I have a RESTFUL API in Drupal for showing a list of events. To get that list of events in my hybrid app (Angular+cordova), I will make a $hhtp call. During that call, I need to send a auth code. How to do it? And how can I be sure, its from iOS or Android or Desktop?
I am thinking of using - MD5 (angular md5) for this. But, what are the encode and decode method for it which will be supported by both AJS and Drupal at the backend.
I think, you need json web token authentication
https://github.com/easystreet3/angular-drupal
https://www.drupal.org/project/jwt

localhost is appending to RequestURL while $http.post using angularjs

I am using json-server(https://github.com/typicode/json-server) as a mock server.My json server runs # 127.0.0.1:3001. When i am trying to post data to that json server using $http.post() from my application which runs at localhost:3000. Its posting like http://localhost:3000/127.0.0.1:3001/tasks/....
When i look some other posts they were suggesting to enable CORS at server end. But i donno how to enable CORS to json server. Can any1 help me out for this.
Code:
return $http.post(config.baseURL+"/tasks"+app,{headers: {'Content-Type': 'application/json'} })
.then(success)
.catch(fail);
Kindly help. config.baseURL has 127.0.0.1:3001.
PFA Screenshot too
Looking forward for help from techies...

Node.js and Angular routing - How to make REST API inaccessible by browser URL

I use Angulars $http service to call for data on the backend. Let's say JSON data. An example URL to do so would be something like:
/get/data
Doing this from within Angular nicely returns the requested data. No problem.
But even though I catch all other Angular routes using Angular UI Router with $urlRouterProvider.otherwise('/');, I can still go to my browser and type in the mydomain.com/get/data URL, which provides me with a page of JSON code.
How to I restrict back-end server calls to come just from Angular, NOT from my browser URL without user authentication?
N.B.
Using Express 4.X on Node, I also provided my app with a 'catch-all' route to default back to my front-end index.html page, like so:
router.get('*', function(req, res) {
res.sendFile(path.join(__dirname, '/index.html'));
});
Thanks!
My God! Spent whole frikin day fighting this problem, finally fixed it!
The dog is burried in headers - you have to specify one on Angular http request, then read it in node.
First of - routing setup is the same as in this guide: https://scotch.io/tutorials/setting-up-a-mean-stack-single-page-application
On frontend in Angular http request I specify one of the accepted header types to be json:
$http.get('/blog/article', {
headers: {
'Accept': 'application/json;'
}
}).success(function(data) {
console.log(data);
})
.error(function(data) {
console.log('Error: ' + data);
});
On backend in Node I check if header includes json type. If it does, I serve back json data, so angular can receive the content. If it doesn't, I force node to load index.html, from which the controller runs the before mentioned http request with the header, ensuring you get your data then.
app.get('/blog/article', function(req, res) {
if(/application\/json;/.test(req.get('accept'))) {
//respond json
//console.log("serving json data...");
blogItemModel.find({ "_id" : req.query.id }, 'title full_text publish_date', function(err, blog_item){
// if there is an error retrieving, send the error. nothing after res.send(err) will execute
if (err) res.send(err);
res.json(blog_item);
});
} else {
//respond in html
//console.log('Request made from browser adress bar, not through Angular, serving index page...');
res.sendfile('./public/views/index.html');
}
});
Agree with #HankScorpio
Angular UI routing for Angular application paths and server application accessing URL paths are two different things.
Angular UI router allows you to navigate within a single page application as if you have a multi page application. This is in no way similar to accessing the actual server application endpoint.
All restrictions should be done on the web server and server web application end. Hence you will have to implement some authentication/authorisation strategy.
This isn't really an angular issue. When a user enters mydomain.com/get/data they never actually load up the angular app, so your solution must be done elsewhere.
For example, you could add this to your website's .htaccess file. It will redirect all traffic to the root of your domain.
Check out this answer here:
.htaccess Redirect based on HTTP_REFERER
You can't.
Your angular code is running on their machine, in their browser.
As such, one can spoof the environment, capture the data as the browser requests it, edit the JS of your app while it is in their browser, or various other methods.
Why do you want such a restriction anyway?

Angularjs - $resource causing a 404 - method: OPTIONS

I am trying to get a basic $resource request via angularjs. I am running this on my local computer.
However, I get a 404. A simple get request on the browser loads the json.
Here is the request shown by chrome devtools. (Question: why is the request mode: OPTIONS? Could that be the problem?)
Request URL:http://example.com/api/rentable_properties.json
Request Method:OPTIONS
Status Code:404 Not Found
Here is my controller that is attempting to make the request:
'use strict';
angular.module('adminApp')
.factory('Property', function($resource)
{
return $resource('http://example.com/api/rentable_properties.json/:propertyId');
});
angular.module('adminApp')
.controller('PropertiesCtrl', function ($scope, Property, $location) {
$scope.properties = Property.query()
The answer here is that your browser is running into a cross domain issue
See http://metajack.im/2010/01/19/crossdomain-ajax-for-xmpp-http-binding-made-easy/ for an explanation and Why am I getting an OPTIONS request instead of a GET request? for a question basically the same as yours.
As mentioned by #JSager, the problem was a cross domain issue.
Since I had control over the server side (running a Rails server), I had to change the server to it to receive cross-site requests.
In my case, I had to install a gem and follow it's instructions.
https://github.com/cyu/rack-cors
This fixed the issue for me. No changes made on the Angularjs based app.

Resources