CSRF token mismatch - csrf-token

I really frustrating with this error, I have datatable with ajax post request, but the error CSRF token mismatch rarely appear.
this my jquery ajax post setup
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
ajax:{
"url": "trip/jsondata",
"dataType": "json",
"type": "POST",
"data" : function ( d ){
d.nState= $('#viewoption').val(),
d.nYear = $('#viewyear').val();
}
},
I courious why my post request return CSRF token mismatch, so I've modified the Illuminate\Foundation\Http\Middleware\VerifyCsrfToken file to return the token values like below.
public function handle($request, Closure $next)
{
if (
$this->isReading($request) ||
$this->runningUnitTests() ||
$this->inExceptArray($request) ||
$this->tokensMatch($request)
) {
return tap($next($request), function ($response) use ($request) {
if ($this->shouldAddXsrfTokenCookie()) {
$this->addCookieToResponse($request, $response);
}
});
}
$error='getTokenFromRequest :'.$this->getTokenFromRequest($request).' | X-CSRF-TOKEN :'.$request->header('X-CSRF-TOKEN').' | Session :'.$request->session()->token();
throw new TokenMismatchException('CSRF token mismatch. err: '.$error);
}
I Try to return 3 variables (getTokenFromRequest, X-CSRF-TOKEN, and the Session token).
And the result is:
message: "CSRF token mismatch. err: getTokenFromRequest :w0nxu5OPWZHFrBFqMtLsL3IWJ1vCg0VAGbCDt4c3 | X-CSRF-TOKEN :w0nxu5OPWZHFrBFqMtLsL3IWJ1vCg0VAGbCDt4c3 | Session :CiMUsbN9BumKIElvrOzJX8TnCA8UeuAAaLzbfZTO"
You can see there is a different between X-CSRF-TOKEN with Session Token, I don't know why?
Then I try to check in the storage\framework\sessions folder, there are two files.
The first file filled like this
a:7:{s:6:"_token";s:40:"w0nxu5OPWZHFrBFqMtLsL3IWJ1vCg0VAGbCDt4c3";
The second file filled like this
a:2:{s:6:"_token";s:40:"CiMUsbN9BumKIElvrOzJX8TnCA8UeuAAaLzbfZTO";
Anyone can help what's happen in my application? is it normal have 2 sessions at the same time with a different token?

Related

Fetching resources from google analytics services using HTTPS by Wix fetch function

How should I fetch data using Wix-fetch function?
I followed this google analytics API tutorial, this tutorial using post function for getting JSON data, I used WIX fetch function to get JSON file, but the return object is undefined.
What did I miss?
fetch( "https://accounts.google.com/o/oauth2/token", {
"method": "post",
"headers": {
"Content-Type": 'application/x-www-form-urlencoded'
},
'body' : JSON.stringify({
'grant_type': 'authorization_code',
'code': URLCode,
'client_id': 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com',
'client_secret': 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx',
'redirect_uri': 'https://www.mydomain.or/ga/oauth2callback'
})
} )
.then( (httpResponse) => {
if (httpResponse.ok) {
return httpResponse.json();
} else {
return Promise.reject("Fetch did not succeed");
}
} )
.then( (json) => console.log(json.someKey) )
.catch(err => console.log(err));
UPDATE
STEP 1
I used this URL to generate the CODE
wixLocation.to("https://accounts.google.or/o/oauth2/auth?scope=https://www.googleapis.com/auth/analytics%20https://www.googleapis.com/auth/userinfo.email&redirect_uri=https://www.mydomain.or/ga/oauth2callback/&access_type=offline&response_type=code&client_id=XXXXXXXXXXXXXXXXXX")
I get the CODE from the callback URL
Step 2
I used this code for the HTTP postman request
The redirect URI in step 1 and 2 is the following (the second one):
Step 1:
There needs to be an exact match between the redirect URI configured in the client id in the google developers console and the URL to get the code authorization.
The URL should be built as shown in the tutorial you linked (if you need a refresh token, you can add the access_type=offline)
https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com/auth/analytics&redirect_uri=<redirect_uri>&response_type=code&client_id=<client_id>
After you enter the URL, you will be provided with an authorization window. Once you authorize, you will be redirected to the <redirect_uri> you provided earlier. You will find the code as the first parameter in the URL query. e.g. <redirect_uri>/?code=<auth_code> ...
Since the access token is for one-time use only, if you will need it again, you will have to get a new <auth_code>.
Step 2 (Postman query example):
If you got the access_token correctly and you want to check now with WIX. Get a new <auth_code> (as said, the access token is given once) and set the code as follows:
import { fetch} from 'wix-fetch';
$w.onReady(function () {
const data = `grant_type=authorization_code&code=<your_authorization_code>&client_id=<your_client_id>&client_secret=<your_client_secret>&redirect_uri=<your_redirect_uri>`;
fetch("https://accounts.google.com/o/oauth2/token", {
"method": "post",
"headers": {
"Content-Type": 'application/x-www-form-urlencoded'
},
'body': data
})
.then((httpResponse) => {
if (httpResponse.ok) {
return httpResponse.json();
} else {
return Promise.reject("Fetch did not succeed");
}
})
.then((json) => console.log(json.access_token))
.catch(err => console.log(err));
});

Http post request with body parameters not working

Recently I started developing a small application in Flutter. I have an issue with making a network request. I have tried the call in postman and there it work. But in Flutter I never managed to make it work, I have spent like 3 hours trying to understand what I am doing wrong.
Any help will be greatly appreciated.
#override
Future<String> login(common.LoginParameters loginParameters) async {
try {
final String loginURL = "https://test.example.eu/api/login";
LoginModel loginResult;
Map bodyParams = { "inlognaam" : loginParameters.username , "wachtwoord" : loginParameters.password, "code" : loginParameters.smsCode};
//await API call
http.Response httpResponse = await http.put( loginURL, body: json.encode(bodyParams));
if (httpResponse.statusCode == 200) {
// If server returns an OK response, parse the JSON
loginResult= LoginModel.fromJson(json.decode(httpResponse.body));
} else {
// If that response was not OK, throw an error.
throw Exception('Failed to load post');
}
// if logged in get token, Otherwise return error
if (loginResult.ingelogd) {
// read the token
saveToken(loginResult.response);
return "Ingelogd";
} else {
return loginResult.error;
}
}
on Exception catch(error) {
print("Todor " + error.toString());
return "Controleer uw internet verbinding en probeer opnieuw";
}
}
In Postman if I select Post request with body parameters
inlognaam : someUsername
wachtwoord : somePassword
code : someCode
Then I get a success response
I pass the parameters in the following way, maybe it can work for you:
var response = await http.post(
url,
headers:{ "Accept": "application/json" } ,
body: { "state": 1}, //key value
encoding: Encoding.getByName("utf-8")
);
Another thing, you say that in postman you make a post request, but in your code you have a put request, verify what is the correct method

BreezeJS intercept server response

Due to an issue with ASP.NET Identity 2.0, the server returns HTTP 200 with a message saying HTTP 400 and I am trying to intercept it in order to redirect the user to the login page. This is the code I have but it seems that the site does not progress any longer. I understand that the issue is resolved in ASP.NET Identity 3.0 but it is not an option right now. Any ideas on the code below?
var ajaxAdapter = breeze.config.getAdapterInstance('ajax');
ajaxAdapter.requestInterceptor = function (requestInfo) {
requestInfo.success = function (response) {
// process response message here.
return response;
}};
I ended up fixing this by assigning the original success function to a variable and then calling it after my own code:
var ajaxAdapter = breeze.config.getAdapterInstance('ajax');
ajaxAdapter.requestInterceptor = function (requestInfo) {
var oldSuccessFn = requestInfo.success;
requestInfo.success = function (data, statusText, jqXHR) {
if (data.Message == "Authorization has been denied for this request.") {
signOut();
} else {
var result;
oldSuccessFn.call(result, data, statusText, jqXHR);
return result;
}
},

AngularJS - Unknown provider configuring $httpProvider

In the following code example:
myApp.config(['$httpProvider', function($httpProvider, $cookieStore) {
$httpProvider.defaults.withCredentials = true;
$httpProvider.defaults.headers.get['Authorization'] = 'Basic '+ $cookieStore.get('myToken');
return JSON.stringify(data);
}]);
I get an angularjs error like 'Unknown provider $cookieStore'.
'myApp' has dependenciy and 'ngCookies' and angular-cookies.min.js is laoded, so what's wrong with that code ?
Is that fact that i'm doing this in .config ?
Because it's only possible to pass providers when configuring, i have finally done the overwrite of my http parameter not with a request transformer but by creating a service as factory to do requests.
Here is a code example of the service (not tested, just for information):
angular.module('myapp-http-request', []);
angular.module('myapp-http-request')
.factory('MyRequests', function($http, $cookieStore){
return {
request: function(method, url, data, okCallback, koCallback){
$http({
method: method,
url: url,
data: data
}).success(okCallback).error(koCallback);
},
authentifiedRequest: function(method, url, data, okCallback, koCallback){
$http({
method: method,
url: url,
data: data,
headers: {'Authorization': $cookieStore.get('token')}
}).success(okCallback).error(koCallback);
}
}
});
And example of usage (not tested, just for information):
angular.module('sharewebapp', ['myapp-http-request'])
.controller('MyController', ['MyRequests', function(MyRequests){
MyRequests.authentifiedRequest('DELETE', '/logout', '', function(){alert('logged-out');}, function(){alert('error');})
}]);
You probably need to add the cookieStore
myApp.config(['$httpProvider', '$cookieStore', function($httpProvider, $cookieStore)
I had ran into this same problem so i'll post how I got around it. I essentially used the $injector module to manual grab an instance of the service I needed. Note this also works for user defined services.
angular.module('app').
config(config);
config.$inject = ['$httpProvider'];
function config($httpProvider) {
//Inject using the $injector
$httpProvider.interceptors.push(['$injector', function($injector){
return {
request: function(config) {
//Get access by injecting an instance of the desired module/service
let $cookieStore = $injector.get('$cookieStore');
let token = $cookieStore.get('your-cookie-name');
if (token) {
config.headers['x-access-token'] = token;
}
return config;
}
}
}])
}
Using the Module.run() seems to be a cleaner way to set headers that are always needed. See my answer here: AngularJS pass requestVerificationToken to a service

ASP .NET 4 Wev Api controller - modify response type

Let’s say I’ve got a simple Web API controller. I want to return a basic .NET type as a result. For example:
public class LoginController : ApiController
{
[HttpPost]
public bool Authenticate(LoginUserViewModel loginUserViewModel)
{
return true;
}
}
I’m getting different results in different browsers even if the request is exactly the same for all of them.
In Chrome and IE7 I get Content-Type in Response Headers as application/json; charset=utf-8, and response value equal to "true".
Firefox recognizes response Content-Type as application/xml; charset=utf-8 and sets response value to:
"<boolean xmlns="http://schemas.microsoft.com/2003/10/Serialization/">true</boolean>"
Is there any way to set response type on the server-side so it is always the same?
Thanks.
UPDATE: Here is JavaScript that I use to call my controller.
Ext.Ajax.request({
async: false,
url: 'Login/Authenticate',
defaultHeaders: { 'Accept': 'application/json' },
jsonData: user,
success: function (response, options) {
if (response.responseText !== 'true') {
Ext.Msg.alert('Error', 'Login failed, please try again');
} else {
document.location = 'Main.aspx';
}
},
failure: function (response, options) {
Ext.MessageBox.hide();
Ext.Msg.alert('Error', 'Server error. Cannot authenticate user.');
}
});
This is because browsers send different Accept headers. Web API uses the accept header to determine the content-type of the response. By default Web API loads up a few different formatters into it's configuration.Formatters collection.
One way to force the response of to be a specific media-type is to remove all the existing formatters and add only the one you want.
configuration.Formatters.Clear();
configuration.Formatters.Add(new JsonMediaTypeFormatter());

Resources