I have gone through multiple documents , Including ng-cordova and oauth-ng but I still can’t find any resource which deals with a basic token based authentication in angularjs/Ionic
I am having trouble about how to make this curl call in angularjs
curl -X POST -vu sampleapp:appkey http://sampleurl/oauth/token -H "Accept: application/json" -d "password=pwd&username=sampleuname&grant_type=password&scope=read%20write&client_secret=appkey&client_id=sampleapp"
I am doing this and it’s giving me a 401
error. However a curl call works just fine.
$scope.login = function() {
$http({
method: "post",
url: "http://sampleurl/oauth/token",
data: "client_id=" + clientId + "&client_secret=" + clientSecret + "password=pwd&username=sampleuser&grant_type=password" + "&scope=read%20write",
withCredentials: true,
headers: {
'Content-Type': 'application/json; charset=utf-8'
}
})
.success(function(data) {
accessToken = data.access_token;
$location.path("/secure");
})
.error(function(data, status) {
alert("ERROR: " + data);
});
}
I realise that once I get the token , I have to do something similar to
$http.get('http://apiurl/api/v1/users',
{headers: { Authorization: ' Token api_key=xxxxxxxxxxxxxxxxxxxxxxxxxxxx'}})
.then(function(response) {
service.currentUser = response.data.user;
console.log(service.currentUser);
});
But so far I’ve been unable to figure out a way to make a call to the server and save the access token in my localstorage. All resources on the internet are primarily catered towards 3rd party logins (google,facebook,twitter etc ) or JWT tokens.
I am fairly new at this but I’ve found out that I need to worry about password grant flow where the user gives his/her credentials to the consumer and the consumer exchanges these for an access and refresh token. Still I don’t believe I am making the right call.
oauth-ng seemed like a good solution but their documentation from what I’ve seen confuses me as I want to send the username and password to the url too and the sample is not implementing it or has a provision for it from what I can tell?
This is what they have in their documentation :
<oauth
site="http://oauth-ng-server.herokuapp.com"
client-id="d6d2b510d18471d2e22aa202216e86c42beac80f9a6ac2da505dcb79c7b2fd99"
redirect-uri="http://localhost:9000"
profile-uri="http://oauth-ng-server.herokuapp.com/api/v1/me"
scope="public">
</oauth>
Again , this is a first time I’m trying integration of any kind and it makes sense for me to think that the call will have credentials sent with it? How do I send it then ?
On the suggestion of building interceptors to handle authentication , I went ahead and built one and for now , I believe everything works good apart from the fact I don’t know how to send my client ID or secret to my post request .
I’m getting a 401
for Full authentication is required to access this resource
here’s my app.js
var app = angular.module('AngularAuthApp', ['ngRoute', 'LocalStorageModule', 'angular-loading-bar']);
app.config(function ($routeProvider) {
$routeProvider.when("/home", {
controller: "homeController",
templateUrl: "/views/home.html"
});
$routeProvider.when("/login", {
controller: "loginController",
templateUrl: "/views/login.html"
});
$routeProvider.otherwise({ redirectTo: "/home" });
});
app.run(['authService', function (authService) {
authService.fillAuthData();
}]);
app.config(function ($httpProvider) {
$httpProvider.interceptors.push('authInterceptorService');
});ig(function ($httpProvider) {
$httpProvider.interceptors.push('authInterceptorService');
});
Here’s my authService.js
app.factory('authService', ['$http', '$q', 'localStorageService', function ($http, $q, localStorageService) {
var serviceBase = 'http://url/oauth/';
var authServiceFactory = {};
var _authentication = {
isAuth: false,
userName : ""
};
var _login = function (loginData) {
var data = "grant_type=password&username=" + loginData.userName + "&password=" + loginData.password ;
var deferred = $q.defer();
$http.post(serviceBase + 'token', data, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }).success(function (response) {
localStorageService.set('authorizationData', { token: response.access_token, userName: loginData.userName });
_authentication.isAuth = true;
_authentication.userName = loginData.userName;
deferred.resolve(response);
}).error(function (err, status) {
_logOut();
deferred.reject(err);
});
return deferred.promise;
};
authServiceFactory.login = _login;
return authServiceFactory;
}]);
Here’s my authInterceptorService.js
app.factory('authInterceptorService', ['$q', '$location', 'localStorageService', function ($q, $location, localStorageService) {
var authInterceptorServiceFactory = {};
var _request = function (config) {
config.headers = config.headers || {};
var authData = localStorageService.get('authorizationData');
if (authData) {
config.headers.Authorization = 'Bearer ' + authData.token;
}
return config;
}
var _responseError = function (rejection) {
if (rejection.status === 401) {
$location.path('/login');
}
return $q.reject(rejection);
}
authInterceptorServiceFactory.request = _request;
authInterceptorServiceFactory.responseError = _responseError;
return authInterceptorServiceFactory;
}]);
I am not sure as to where to send my clientID and secret . Sending it part of the data
variable doesn’t work and I’m not sure if the scope
should be sent too (as per the curl call) .This is where I am stuck at the moment.