In an app using AngularJS and Ionic, what is the best way to authenticate to an API? Do I check login on all screens or do I use some session engine?
I guess authentication on all controllers may consume too much data ... What is the best way?
In an app using AngularJS and Ionic, what is the best way to authenticate to an API? Do I check login on all screens or do I use some session engine?
I guess authentication on all controllers may consume too much data ... What is the best way?
The ideal is to use APIs that support OAuth 2, you then perform the initial procedures to get the bearer token and store it in a cookie to be used on every request to the API (or at least the endpoints that require this authentication). I'm going to give you an example of a service that I'm using in an application to perform all authentication procedures with an API that makes use of OAuth 2.
Here is the service code:
(function () {
'use strict';
angular
.module('zigforumApp')
.service('users', users);
users.$inject = ['$http', '$cookies', 'TOKEN_URL'];
function users($http, $cookies, TOKEN_URL) {
var sv = this;
function NoAuthenticationException(message) {
this.name = 'AuthenticationRequired';
this.message = message;
}
function AuthenticationExpiredException(message) {
this.name = 'AuthenticationExpired';
this.message = message;
}
function AuthenticationRetrievalException(message) {
this.name = 'AuthenticationRetrieval';
this.message = message;
}
sv.userData = {
isAuthenticated: false,
username: '',
bearerToken: '',
expirationDate: null
};
function isAuthenticationExpired(expirationDate) {
var now = new Date();
expirationDate = new Date(expirationDate);
if (expirationDate - now > 0) {
return false;
} else {
return true;
}
}
function saveData() {
removeData();
$cookies.putObject('auth_data', sv.userData);
}
function removeData() {
$cookies.remove('auth_data');
}
function retrieveSavedData() {
var savedData = $cookies.getObject('auth_data');
if (typeof savedData === 'undefined') {
throw new AuthenticationRetrievalException('No authentication data exists');
} else if (isAuthenticationExpired(savedData.expirationDate)) {
throw new AuthenticationExpiredException('Authentication token has already expired');
} else {
sv.userData = savedData;
setHttpAuthHeader();
}
}
function clearUserData() {
sv.userData.isAuthenticated = false;
sv.userData.username = '';
sv.userData.bearerToken = '';
sv.userData.expirationDate = null;
}
function setHttpAuthHeader() {
$http.defaults.headers.common.Authorization = 'Bearer ' + sv.userData.bearerToken;
}
this.isAuthenticated = function () {
if (!(sv.userData.isAuthenticated && !isAuthenticationExpired(sv.userData.expirationDate))) {
try {
retrieveSavedData();
} catch (e) {
return false;
}
}
return true;
};
this.removeAuthentication = function () {
removeData();
clearUserData();
$http.defaults.headers.common.Authorization = null;
};
this.authenticate = function (username, password, persistData, successCallback, errorCallback) {
this.removeAuthentication();
var config = {
method: 'POST',
url: TOKEN_URL,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: 'grant_type=password&username=' + username + '&password=' + password
};
$http(config)
.success(function (data) {
sv.userData.isAuthenticated = true;
sv.userData.username = data.userName;
sv.userData.bearerToken = data.access_token;
sv.userData.expirationDate = new Date(data['.expires']);
setHttpAuthHeader();
if (persistData === true) {
saveData();
}
if (typeof successCallback === 'function') {
successCallback();
}
})
.error(function (data) {
if (typeof errorCallback === 'function') {
if (data && data.error_description) {
errorCallback(data.error_description);
} else {
errorCallback('Unable to contact server; please, try again later.');
}
}
});
};
try {
retrieveSavedData();
} catch (e) { }
}
})();
The most important function is authenticate
it receives the user login data, makes an API request to get the token , stores the token in a cookie and to automatically authenticate all requests that will be made from here onwards it adds that token as the default header.
You can use this service as a basis to build your own.
The best way to sign in with AngularJS is ...
Seriously. Being a technology that runs on the client, any credential validation rule (connecting to an endpoint to verify user and password, for example) can be exploited by a malicious user.
The best way, in this case, would involve delegating responsibility for sign-in and sign-out actions to another part of the application - in the well-given example of Zignd , this technology would be OAuth .
The end result of an OAuth tightening is a token , which can be stored in LocalStorage or in a cookie. Use this token to get information about the currently logged in user.