I am using angular ui as a separate package and for the backend I am using laravel backend.Now if I bypass the csrf token in laravel I can handle the post request from separate angular package but for security I will have to use csrf in post requests.I am not using middleware.Can anyone help me in this regard?
Based on my knowledge: Tern off laravel default token behavior by commenting middleware line(As you already did).
Don't afraid with this because you can use jwt-auth to pass token along with the request to protecting your request/API with the middleware that comes with jwt-auth. You can get more detail from here.
You could create an API in Laravel, which return CSRF Token, such as:
Route::get('api/token', function() {
return Session::token();
});
Of course you need to add validation on the controller or middleware, etc. For example in controller:
public function list() {
if (Session::token() != $request->header('X-Csrf-Token') )
return Response::json('CSRF does not match', 400);
// Other code
}
In your angularjs code, you could get the token and register it as a constant and could be injected in all angularjs HTTPRequest to the api:
var xhRequest = new XMLHttpRequest();
xhRequest.open("GET", "api.yourdomain.com/api/token", false);
xhRequest.send(null);
app.constant("CSRF_TOKEN", xhRequest.responseText);
app.run(['$http', 'CSRF_TOKEN', function($http, CSRF_TOKEN) {
$http.defaults.headers.common['X-Csrf-Token'] = CSRF_TOKEN;
}]);
Related
I'm migrating a JSP/Spring project to Angular JS 1.X. Currently I'm stuck in following situation, appreciate if anyone can help.
My application is redirecting to a 3rd party app and after submitting a form response is coming back to again my application. In spring I used to get the request parameter using following code. How can I get the request parameters in Angular JS?
#Autowired
private HttpServletRequest request;
..
Enumeration paramsEnum = request.getParameterNames();
while (paramsEnum.hasMoreElements()) {
String paramName = (String) paramsEnum.nextElement()
....
}
Not sure I understood the question because with Java/Spring we access the params sent by angularJS.
Anyway, If you want to access a Url parameters of the current view you can use the angularjs $location service:
$location.search()
For example taking the 'impersonate_token' from the url and adding it to some variable:
if($location.search().token){
var token = $location.search().token;
url += "?impersonate_token=" +token;
}
if you want to manage the Url parameters send to the server side, you can do with angularjs $http service like this:
$http({
url: your/url,
method: "GET",
params: {
param_1: $scope.some_data
param_2: $scope.some_data2
}
});
$http.get(url)
.then(function(response) {
$scope.myWelcome = response.data;
});
I get follow scenario which is working now:
MVC controller using System.Web.Mvc.AuthorizeAttribute to authenticate user is authenticated or not, it will be using cookie.
API controller using System.Web.Http.AuthorizeAttribute to authorise with bearer token.
I do also have angular http interceptor that verify and get bearer token for API purpose that can use among all angular $http request. But I am confusing how to achieve both after user has login?
This is current workflow
User click login, angular verify and store bears token in local storage.
After complete, manually trigger MVC controller so that it will get cookie for MVC authenticate.
This seem to me really double job, or I should focusing on using one AuthorizeAttribute?
You need you use Authorize key to give permission to those functions where authorization is needed. And those functions can only be accessed when authorization token is generated and passed with http request.
module.service('tokenservice', function ($http) {
this.get = function () {
var accesstoken = sessionStorage.getItem('accessToken');
var logged_in = localStorage.getItem('logged_in').toString().trim() === 'false' ? false : true;
var authHeaders = {};
if (accesstoken && logged_in) {
authHeaders.Authorization = 'Bearer ' + accesstoken;
}
return authHeaders;
};
});
module.controller('yourControllerName', function ( $http, tokenservice) {
$http({
method: "POST",
url: '/Controller/MyFucntion',
headers: tokenservice.get(),
});
});
This will help you to get generated token in user login. After that You need to work with your controller
[Authorize]
public JsonResult MyFucntion()
{
//Your logic and calculation
//return
}
Hope that will help
hello everyone, i'm building a web application using "angularjs" as a front-end and using "codeingniter" as a back-end, however when i request an request with angular using "$http" built in services, it returns data nicely, so my problem is that when i check if request is ajax using built in function in "codeigniter" :$this->input->is_ajax_request() the result will be not ajax request could any one help me to solve this problem thanks a lot for all
Add HTTP_X_REQUESTED_WITH header to $http requests to match what is_ajax_request() looks for as per CI docs .
You can set as defaults or on per request basis or in httpInterceptor. $http doesn't seem to use it and there is no mandatory spec for any HTTP_X*** series headers
saw this https://forum.codeigniter.com/thread-65552.html
he fix this by
dgApp.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
$httpProvider.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest";
$httpProvider.interceptors.push(['$q', function($q) {
return {
request: function(config) {
if (config.data && typeof config.data === 'object') {
config.data = $.param(config.data);
}
return config || $q.when(config);
}
};
}]);
}]);
works for me tho.
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.
How to create post request using angular.js and drywall (user management system) which needs csrf token ?
Some more information or a little bit of code of your side would be helpful. But I'll try:
A basic POST request would look sth like this:
function login() {
return $http.post('your-domain.com', {someData: "foobar"}).success(function(response) {
// do something with your data
}).error(function(error) {
// do something with the error
});
}
If you want to include the CSRF token for every request, you can read it out of your HTML code, and use the $http.defaults.headers object. Inside your app.js do this:
var yourApp = angular.module("yourApp", [
]).config(function() {
}).run(function($http) {
var csfrToken = $("meta[name='csrf-token']").attr("content");
$http.defaults.headers.post['X-CSRF-TOKEN'] = csfrToken;
});
Depending on your framework that generates the CSRF token, you have to adjust the jQuery selector $("meta[name='csrf-token']").attr("content").