How to secure my authentication headers on Angularjs when accessing REST API - angularjs

I have this angularjs code below to access an API in json format with OAuth2's token. But I noticed writing in this way the access token can be seen and captured by everyone. I wonder how to hide or secure this so that no one can get the token easily by just checking the source.
<script>
var app = angular.module('myApp', []);
app.controller('articleCtrl', function($scope, $http) {
$http({
url: "http://example.com/api/article",
method: "GET",
headers: {
"Authorization": "Bearer bVM1HTeZ5R0HETGSTdjeg",
},
}).success(function(response) {
$scope.items = response;
});
});
</script>

You should use a HTTPS/SSL protocol to stablish communication with your REST API

You'll need to communicate with the API on the serverside and send the results to the client. There is no other way. People will be able to view your sourcecode, it's sent to the client so it can be executed. At that point it's in the hands of your client and they have your key. You could obfuscate your sourcecode but if somebody wants to, it's easy to undo. Just do API calls on your serverside through PHP/Node or whatever you are running and send the results to your client. The client isn't able to read your serverside code so your key will be safe. So instead of: API <> Client you'll need to do API <> server <> client

Related

Accessing Django server from AngularJs App: Easy authentication solution?

I've been looking everywhere but can't seem to find an answer that has been helpful.
I have written an angular app that is trying to pull data from a django RESTful backend that was written by my company. I have a username and password, but I'm not sure how to write the get request to provide the authentication credentials to the backend. I'm also confused about what exactly I'm supposed to provide in the header.
Eventually, we will be communicating using nginx.
What I want
I'm looking for a fix to write in the angular app itself. I'm trying to write the angular app as separate as possible from the django backend. I have already enabled cross origin resource sharing.
This will be a band aid fix just to display data from the backend. It does not need to be permanent by any means.
So far I have tried:
app.factory('mySamples', ['$http', function($http) {
return $http.get('website/api/foo', {
headers: {'username':"foo", 'password': 'bar'}
}).success(function(data) {
return data;
}).error(function(err) {
return err;
});
};
app.factory('mySamples', ['$http', function($http) {
return $http({method: 'GET', url: 'website/api/samples/', headers: {
'user': 'foo', 'auth':'bar'}
});
};
The second factory I wrote returns METHOD: OPTIONS in the networks inspector under returned header. Does anybody have a quick fix just to get data from my api?
EDIT: My django backend doesn't support basic authentication, only session based. How would I edit my get request?
You first need to know what kind of Authentication and Authorization is implemented on the server side i.e. What headers the server looks for authentication/authorization credentials in and what format is expected by the server, then send the credentials under that header key. For example if the sever checks for Authentication credentials in the Authorization header in format username::password then you need to add the headers like
headers: {'Authorization': 'johndoe::password'}
(1) If you are using basic authentication, you can add a basic authentication like so:
app.factory('mySamples', ['$http', function($http) {
var credentials = btoa(username + ':' + authtoken);
var authorization = {
'Authorization': 'Basic ' + credentials
};
return $http({method: 'GET', url: 'website/api/samples/', headers: authorization });
};
If all of your $http calls use this same auth, you can use $http.defaults.headers.common.Authorization
(2) I’m pretty sure nginx does not provide session handling—you’ll have to do that in django.
(3) I don’t typically use sessions with REST since REST is usually done stateless.
OP asked how to enable CORS. Enabling CORS is usually done on the server-side. You can do it in nginx by adding:
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
To the appropriate location block. You can also do this on the django side with middleware pacakges like django-cors-middleware (https://pypi.python.org/pypi/django-cors-middleware) or django-cors-headers (https://pypi.python.org/pypi/django-cors-headers).

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

Secure requests in Angular

I'm learning Angular and i'm using a 3rd party hotel Api to make a live booking request.
The Api says send all request values within the POST body as application/x-www-form-urlencoded
Angular form
Should I use $httpParamSerializer or
$http.post(url, data,{headers: {'Content-Type': 'application/x-www-form-urlencoded'}})
.success(function(response) {
// your code...
});
I have also read that a standard $http request will just send it as default json anyway and is not needed?
What is most secure way for sending from data?

How do cookie authentication on couchdb with angularjs

Hey? Can someone hep me to do cookie authentication on CouchDB with AngularJS?
This my code:
var app = angular.module('app', []);
app.controller('mainController', ['$scope','$http', function($scope,$http){
//Authentification cookie
$http.({
url: 'http://localhost:5984/_session',
method: 'POST',
headers: {
Accept: 'application/json',
Content-Type: 'application/x-www-form-urlencoded'
},
data:{
name: "packy",
password: "packy8"
}
}).then(function(response){
console.log(response.headers);
});
}
The problem? i'm not able to read The AuthSesssion Cookie.
Cookies are sent via HTTP headers. If you got a cookie in response you have to dig into the response headers.
Alternatively you can ask the browser via JavaScript to provide the cookie data that was stored automatically from the response into the browser session.
To receive the AuthSession cookie from CouchDB you need to do a POST request to _session. The cookie you get is marked with a HttpOnly flag so it's tricky if not impossible to read it from the browser (at least I wasn't able to).
Once you have the cookie, GET requests to _session will return the logged in user, you don't need to do anything else. The one issue that I ran into was tricking the browser into prompting the "save password for this website" message, it seems they expect the POST request to be made from a standard HTML form not an ajax request. What I ended up with is a mix between sending a POST request using the Angular $http, then if successful do a full form request to _session as well as setting the "next" query param so I get returned to whatever page I need (otherwise you get stuck on the localhost:5984/_session page).

Authentication using Angularjs

I am fairly new to AngularJS
I have a resource that I use for user management which is part of a service following this article.
Once sending the login request to the server I am getting a response with a set-cookie as part of the header.
What is the best practice to add this cookie to every request I am sending to the server?
myApp.factory('UserService', ['$resource', function ($resource) {
var userRes = $resource('http://<MyDomain>/api/v1/user/:param',
{param: '#param'},
{
login: {
method: 'POST'
},
logout: {
method: 'DELETE'
}
});
var user;
return {
signIn: function () {
user = userRes.login({param: 'login'}, {"email": "SomeName#MyDomain.com", "password": "test1"});
userRes.get({param: '1'});
},
userRes.login has set-cookie header in on the response
userRes.get does not send the cookie that was just received.
Cheers
Since your API is in a different domain you can't use cookies in this case. We've tried and we failed to put it simple there is no way, not only it doesn't work with CORS but also it doesn't work if you embed an iframe. The iframe trick fails on safaris mostly but it is not reliable.
What we usually do is to return a JWT (Json Web Token) from the API and attach a header then to every API request as Authorization: Bearer JWT.
This JWT can be decoded using a public key from the front end (and it will contain the user profile) and validad with a private key in the backend.
JWT is simple and there are plenty of libraries for every language/technology.
Auth0 is an authentication broker that can validate with any identity provider or custom databases, and it returns JWTs using standars. It provides a clientID that can be used to decode the profile in the front end and a secret to validate the tokens in the backend as well as client side library to do this.
Disclaimer: I work for auth0.

Resources