I'm working on a web application with Angular.JS and Node.JS as the back-end.
On my login page, I'm using an AJAX call to perform the login. Upon a success login, I would like to redirect the browser to a new page but I need to add the am authorization header based on the login response.
For future AJAX calls I use Angular interceptor to add the token to each request but my problem is how to add it to the redirect call.
$http
.post('/api/authentication/login', dataToPost)
.success(function(data, status, headers, config){
$window.sessionStorage.token = data.token;
window.location.replace("/");
})
Thanks
You can add the headers like this way.
$http.defaults.headers.common.Authorization = $window.sessionStorage.token
Related
I'm new to angular JS. I've followed an online tutorial and created a simple login form on the frontend, and linked it to the backend. Or at least I've tried. The backend is a nodejs/express server, which has a route for handling the login attempts from the frontend. It will be checking to see if the username and password used on the form are from an existing user account, or not.
The problem is that for some reason, the http POST call from the angular controller, always results in a ERR_CONNECTION_TIMED_OUT response in the browser console.
The thing is, though if I interface with the api endpoint using curl, it works just fine and the server does exactly what it's supposed to do. Just for some reason the angular frontend form cannot connect to the backend. Here's the angular controller code:
app.controller('loginCtrl, function($scope, $location, $http){
$scope.login = function(){
var parameter = JSON.stringify({ username: $scope.username, password: $scope.password });
$http({
url: 'https://localhost:8443/api/login'
method: 'POST',
data: parameter
}).then(function(response){
console.log('success: ' + JSON.stringify(response));
},
function(response){
console.log('failed: ' + JSON.stringify(response));
});
}
});
The nodejs backend server is serving content over HTTPS. This controller function (login) is being hit, and the POST is being made, but it simply times out. And again, manually interfacing with these api endpoints works as expected when using curl or wget.
Any insight into the issue or what I'm doing wrong?
Can anyone say me how to auto login with angularjs 1.x .I will be sending the email with url and when they click on that url it should autoredirect to home page.
The url will be having email and encrypted password:
http://localhost:8080/login/amg1.2.3#outlook.com/$2a$08$cZPWmzta7Gn9Mj14r7zGWeMPKNKkkg8JS3gWNL2fQaFuBwrhgKQC
Clicking on this url should redirect me to home page without any login page.
I am using passport for login functionality.
can you explain me how,iam using passport with form post like this
app.get('/login/:email/:pwd', function(req, res) {
console.log(req.params.email);
console.log(req.params.pwd);
var request = require('request');
request.post({
headers: {'content-type' : 'application/x-www-form-urlencoded'},
url: 'http://localhost:8080/login/',
form: { email: req.params.email,password:req.params.pwd }
}, function(error, response, body){
console.log(error);
console.log(body);
console.log(response);
});
});
Please check the gist how I am doing and tell me how can i improve the code gist.github.com/agupta330/0fb55b50eecf4b1305ebfe15869b295d
It has nothing to do with angular, because it is serverside.
You should not use the encryted password, because your link will never expire. It is better to generate a random key and store it in your database like you do it with sessions ids.
If the user clicks on the link an the key is valid and not expires, you generate a new session and send the session cookie together with the redict to your angular page to the user.
For the angular page you not have to change anything, because it seems like the user is loggedin like normal (with the session in the cookie)
I'm building a SPA using Angular.js and ASP.NET and I would like to know what is the best way to secure it.
Here is what I need :
I would like to use MVC framework to hide my application only to logged users. So the first thing that users will do before launching the SPA will be to log into the website using a simple login form.
When the Angular app will be launched, it will communicate with my ApiController using REST requests.
I also want my user to be logged out automatically after 20 minutes of inactivity.
I know that REST is supposed to be stateless... but I can't figure how to implement all I need without sessions...
But on the other side, I want to be able to use my WebAPI with a future mobile application. I will have to use Tokens for the authentication on this application.
What is the best way for me to achieve that kind of authentication?
Thanks for your time!
I developed an entire security layer with the same conditions as yours following those very well explained in this post here.
BTW, the token will expire automatically after 20 minutes because when you create it you will set it's expiration date immediately; every time you're going to make a request, the system will check the token exp date with the current date, refusing your token if the time passed. For example this a tipical oauth server configuration with token and refresh token settings:
internal static OAuthAuthorizationServerOptions GetAuthorizationServerOptions(IComponentContext scope)
{
OAuthAuthorizationServerOptions oAuthServerOptions = new OAuthAuthorizationServerOptions
{
AllowInsecureHttp = true,
ApplicationCanDisplayErrors = true,
TokenEndpointPath = new PathString(Constants.PublicAuth.OAUTH_TOKEN_PATH),
AuthorizeEndpointPath = new PathString(Constants.ExternalAuth.AUTH_ENDPOINT),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(Constants.PublicAuth.TOKEN_EXPIRATION_IN_MINUTES),
Provider = scope.Resolve<AuthorizationServerProvider>(),
AccessTokenFormat = new CustomJwtFormat(),
RefreshTokenProvider = scope.Resolve<SimpleRefreshTokenProvider>()
};
return oAuthServerOptions;
}
The refresh token is also very useful, but you have to manage the token replacement by yourself; for example in our application we pass every API call through a single service that, if the server responds 401 (unauthorized), it will try to request a new token using the refresh token and then it will try the same call again. Only after the second failure you'll be redirected to the login page.
For example:
function executeCallWithAuth(method, url, payload, params) {
var defer = $q.defer();
debug.logf('{0}: {1}', method.toUpperCase(), url);
$http({ method: method, url: url, data: payload, headers: createHeaders(), params: params }).then(
function(results) { defer.resolve(results); },
function(error) {
if (error.status !== 401) defer.reject(error);
else {
debug.warn(`Call to: ${method}:${url} result in 401, try token refresh...`);
auth.refreshToken().then(
function() {
debug.warn('Token refresh succesfully, retry api call...');
$http({ method: method, url: url, data: payload, headers: createHeaders() }).then(
function(results) { defer.resolve(results); },
function(errors) { defer.reject(errors); });
},
function(tokenError) {
debug.warn('Token refresh rejected, redirect to login.');
$state.go('login');
defer.reject(tokenError);
});
}
});
return defer.promise;
}
and
function createHeaders() {
var headers = {
};
var authData = storage.get('authorizationData');
if (authData) {
headers.Authorization = 'Bearer ' + authData.token;
}
return headers;
}
Using Angular the best way to secure a route is "do not create a route". Basically, you need to load the user profile, and only after that you will create the routes only to the pages he can navigate to. If you don't create the route for a page you don't need to secure that page: Angular will automatically send the user to a 404.
I would secure your WebAPI calls with OAuth2 (you can even use the built in Identity 2.0 provider that comes baked in with it). Keep your WebAPI stateless, use SSL (consider a filter to force it), and use the [Authorize] tags to secure you services. On the MVC side, this will have to maintain state and you will want to have the login form get an OAuth2 token from your WebAPI layer and pass that down into Angular. Set the expiration on this to 20 minutes. You can also use the cookies authentication model here since it will need to be stateful on the MVC side, but all ajax calls made to the WebAPI layer by Angular will need to pass the OAuth2 token as a bearer token in the Authorization request header.
I have an Angular (1.3.8) SPA with a factory method that is attempting to add a basic authorization header before making a cross-domain API call.
The API is an ASPNET WEB API but has CORS totally enabled. The API is using basic auth message handler
The problem is that in the first call to the API there is no AUTHORIZATION header at all even though the code making the API call looks like this:
$http.defaults.headers.common.Authorization = 'Basic blah...';
$http.get('http://my-webapi-url').
success(function(data, status, headers, config) {
...
}).
error(function(data, status, headers, config) {
alert('error ' + status);
});
The API is not receiving an AUTHORIZATION on the initial call, and is rejecting the call with 401 of course. Why isn't there an AUTH header from the start?
I am trying to use AngularJS with an external API. The API uses HTTP Basic for authentication.
I have looked around at how to do this but nothing seems to work. The OPTIONS request is always sent without the Authorization header.
Here is some example code:
var app = angular.module("BE", []);
app.controller("NextCtrl", function ($scope, $http) {
$http.defaults.headers.common['Authorization'] = 'Basic encoded_credentials';
$http.get('http://api-url.com').
success(function(data, status, headers) {
$scope.event = data.Event;
$scope.race = data.Race;
$scope.entrants = data.Entrants
}).
error(function(data, status, headers, config) {
// log error
});
});
How can I make my requests with the Authorization header set for every request?
You can't control that because OPTIONS is sent by a browser. A browser removes any authorization data in OPTION requests (see CORS W3C Recommendation).
In most cases Authorization header for OPTIONS-requests isn't needed because the response includes only CORS headers and doesn't perform any action.