Hi am using basic authentication for webservie integration.
$http.defaults.headers.common['Authorization'] = 'Basic ' + Base64.encode(Username + ':' + password);
$http({method: 'GET', url: 'http:url.com'}).
success(function(data) {
if(data=='' || data==null || data=='undefined'){
var alertPopup = $ionicPopup.alert({
title: 'Info!',
template: 'Invalid Password, or no user found with this Email Address'
});
alertPopup.then(function(res) {
console.log('Invalid Password, or no user found with this Email Address ');
});
}
This code is working fine for me .but my problem is if one user is logedin using username and password.then logged out after that another user try to logged in with different username and password will get the previous user loged in. how to clear the header authentication data?
You could probably redefine the header with
$http.defaults.headers.common['Authorization'] = 'Basic ' + Base64.encode(newUsername + ':' + newPassword)
It seems that,
You have not replaced the Authorization header when
the user logged out
logged in as a different user
Login - call this every time a user logs in
function setCredentials(username, password) {
$http.defaults.headers.common['Authorization'] = 'Basic ' + Base64.encode(username + ':' + password);
};
Logout - call this when a user logs out
function clearCredentials() {
$http.defaults.headers.common.Authorization = 'Basic ';
};
The above snippets simplified from this tutorial - AngularJS Basic HTTP Authentication Example. i recommend reading it
In addition,
Please note that using basic http authentication is insecure because the password passed on each request with no encryption!
As an alternative, you can change basic http authentication to a server side authentication using sessions (comment the server your'e using and i'll link you to example)
If you still decides to keep the basic http authentication, at least use HTTPS !
I've found this solution working:
When initiating a logout, first try making a bad request with a fake user to throw away the currently cached credentials.
I have this function doing the requests (it's using jquery's $.ajax with disabled asynch calls):
function authenticateUser(username, hash) {
var result = false;
var encoded = btoa(username + ':' + hash);
$.ajax({
type: "POST",
beforeSend: function (request) {
request.setRequestHeader("Authorization", 'Basic ' + encoded);
},
url: "user/current",
statusCode: {
401: function () {
result = false;
},
200: function (response) {
result = response;
}
},
async: false
});
return result;
}
So when I try to log a user out, this happens:
//This will send a request with a non-existant user.
//The purpose is to overwrite the cached data with something else
accountServices.authenticateUser('logout','logout');
//Since setting headers.common.Authorization = '' will still send some
//kind of auth data, I've redefined the headers.common object to get
//rid of the Authorization property
$http.defaults.headers.common = {Accept: "application/json, text/plain, */*"};
Related
I'm using basic HTTP auth (without SSL for testing).
The login works fine, we send an $http request with the authorization header and if the login is correct, it works.
For logout, I'm setting the Authorization header to a bad value and sending an $http request to "trick" the server. The server seems to ignore the new changed auth header. I verified with developer tools in FF that the header value is all ones, but the request is still successful.
How do I "logout"? The logout function sends a bad Authorization header, and the browser sends it according to firebug. What's going on? This is a Java EE 7 app with Wildfly 9 and Shiro, if that makes a difference.
Here is the code:
var DataFactory = function($http, $rootScope, $base64, $cookieStore) {
var _debug = false;
function _d(message) {
if (!_debug) {
return;
}
console.log(message);
}
function setDebug(flag) {
_debug = flag;
}
function doLogout() {
_d("Logging out");
$rootScope.globals = {};
$cookieStore.remove('globals');
$http.defaults.headers.common['Authorization'] = 'Basic 111111111111111111';
$http.get(
'http://localhost:8080/myapp/rest/v1/svc')
.then(function(data) {
alert("Logout: " + JSON.stringify(data.data));
}, function(data) {
alert("Logout Error: " + JSON.stringify(data))
});
}
function doLogin(username, password) {
var token = $base64.encode(username + ":" + password);
_d("Logging " + username + " in with token " + token);
$http.defaults.headers.common['Authorization'] = 'Basic ' + token; // jshint
// ignore:line
$rootScope.globals = {
token : token,
username : username
};
$cookieStore.put("globals", $rootScope.globals);
_d("Login finished, globals are: " + JSON.stringify($rootScope.globals));
$http.get(
'http://localhost:8080/myapp/rest/v1/svc')
.then(function(data) {
alert(JSON.stringify(data.data));
}, function(data) {
alert("Error: " + JSON.stringify(data))
});
}
;
return {
setDebug : setDebug,
doLogin : doLogin,
doLogout : doLogout
};
}
Sending your own authorization string within a XHR request will not magically delete the information cached in the browser. Basic authentication has no concept of logging out. The only way to "logout" with basic authentication is to make the credentials invalid at the server, i.e. change username and/or password so that the stored credentials do not work any longer.
In my angular app the global $http headers are defined for every request, like this:
function useBasicAuth(username, hash) {
var encoded = btoa(username + ':' + hash);
$http.defaults.headers.common.Authorization = 'Basic ' + encoded;
}
How to disable sending this information, when for example the user logs out, and the authentication is no longer required?
What I found as a working solution was to redeclare the $http.defaults.headers.common Object so it won't contain the headers.
Example:
function useBasicAuth(username, hash) {
var encoded = btoa(username + ':' + hash);
$http.defaults.headers.common.Authorization = 'Basic ' + encoded;
}
This, however won't delete the cached credentials from the browser. To overcome this, I've made a simple - and not asynch call to generate a bad request on purpose.
This is the function for this in my accountServices factory:
function checkAuth(username, hash) {
var encoded = btoa(username + ':' + hash);
var result = false;
$.ajax({
type: "POST",
beforeSend: function (request) {
request.setRequestHeader("Authorization", 'Basic ' + encoded);
},
url: "user/current",
statusCode: {
401: function () {
result = false;
},
200: function (response) {
result = response;
}
},
async: false
});
return result;
}
To log the user out, I call this function:
function useBasicWithoutAuth() {
accountServices.checkAuth('logout','logout');
$http.defaults.headers.common = {Accept: "application/json, text/plain, */*"};
}
So what this does, is it first sends a request to a protected URL, with a fake and non-existant user, so it's basically the same, as if the prompt would appear to you, and you'd click cancel.
After this has been done, there's no cached data in the browser, we can simply remove the headers from Angular, so it won't send any Authorization information, where it's not needed.
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.
UPDATE : As #DanielCottone in the answer below has mentioned , 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 ?
The best way to solve this is by storing the token in localStorage after authentication, and then using an interceptor to inject the token into your request headers:
$http authentication promise (you need to inject $localStorage)
.success(function(data) {
$localStorage.accessToken = data.access_token;
$location.path("/secure");
})
Authentication interceptor
.factory('AuthInterceptor', function ($q, $localStorage, $rootScope) {
return {
request: function (config) {
if ($localStorage.access_token) {
config.headers['Authorization'] = 'Token api_key=' + $localStorage.token;
}
return config;
},
responseError: function (response) {
if (response.status === 401 || response.status === 403) {
delete $localStorage.access_token;
// Do some kind of redirect to login page here...
}
return $q.reject(response);
}
};
});
To logout, you would just delete the token from localStorage, and all further requests would be redirected to the login page if you get a 401 or 403 from the API.
i am using a web service having basic authentication i.e. below code shows how i calling the web service
var url='http:url.com/;
$http.defaults.headers.common['Authorization'] = 'Basic ' + Base64.encode(Username + ':' + password);
$http({method: 'GET', url: url}).
success(function(data) {
if(data=='' || data==null || data=='undefined'){
var alertPopup = $ionicPopup.alert({
title: 'Info!',
template: 'Invalid Password, or no user found with this Email Address'
});
alertPopup.then(function(res) {
console.log('Invalid Password, or no user found with this Email Address ');
});
return false;
}
else{
var favoriteCookie = $cookies['JSESSIONID'];
window.localStorage['data'] = JSON.stringify(data);
//console.log("LOGIvar: " + data+ " - PW: " + password);
console.log(data);
$state.go('app.tasklists');
return false;
}
}).
i am getting the correct response and all working fine.
But when i logout the app i am using the below code
$cookieStore.remove('JSESSIONID');
$cookieStore.remove('JSESSIONIDSSO');
$http.defaults.headers.common['Authorization']='undefind';
$scope.modal.show();
$state.go('login',{}, {reload: true});
the real problem is when i logedout then try to logged in with incorrect password it getting logged in web service retuning the previous user details.how can i fix this one thanks in advance?
Just to answer your question:
remove cookies and header, then it asks for re-authentication and also clear native application then it is working fine
Hi i am using header authentication for web service call it os working fine.
$http.defaults.headers.common['Authorization'] = 'Basic ' + Base64.encode(Username + ':' + password);
$http({method: 'GET', url: url}).
success(function(data) {
if(data=='' || data==null || data=='undefined'){
var alertPopup = $ionicPopup.alert({
title: 'Info!',
template: 'Invalid Password, or no user found with this Email Address'
});
alertPopup.then(function(res) {
console.log('Invalid Password, or no user found with this Email Address ');
});
problem is if i logged out and then try to login with different username or password it getting logged in with first logged in user .how to remove the header authentication while logout?
Did you try adding
$http.defaults.headers.common['Authorization'] = ''
to your logout call?
Cheers
It's a bit late already but try with:
delete $http.defaults.headers.common.Authorization;
It works for me.