CSRF token mismatch in post request in 3.6 version - cakephp

I have two different apps of cakephp. One has a version 3.5 and other 3.6.
When i used and built 3.5 app i did not have a problem of CSRF matching in post request. But now as i am using 3.6 it is giving me error of CSRF token.
Although in both app's AppController, CSRF component is disable.
//$this->loadComponent('Csrf');
i am using simple post request like this:
$.ajax({
type: "POST",
url: "../user/my_action",
dataType: 'json',
success: function (data) {
set_data(data.response);
}
});
What am i missing? or some configuration i have done wrong?

The latest 3.6 application template now uses the CSRF middleware by default, see your apps src/Application.php file. Unfortunately this change hasn't been documented properly, and hit people by surprise.
Ideally you do not disable it, but instead pass the proper CSRF token alongside with your AJAX requests, you can easily obtain the token from the request object in your view templates, for example in the layout to make it globally available:
<script>
var csrfToken = <?= json_encode($this->request->getParam('_csrfToken')) ?>;
// ...
</script>
You can then easily use it in your AJAX requests:
$.ajax({
headers: {
'X-CSRF-Token': csrfToken
},
// ...
});
See also
Cookbook > Middleware > Cross Site Request Forgery (CSRF) Middleware
Cookbook > Middleware > CSRF Protection and AJAX Requests

Add this code on your $.ajax() function call:
beforeSend: function (xhr) { // Add this line
xhr.setRequestHeader('X-CSRF-Token', $('[name="_csrfToken"]').val());
}, // Add this line

For CakePHP 3.8, this worked for me. In config\routes.php
comment the line as so :
//$routes->applyMiddleware('csrf');

i had the same error, without using ajax, the problem was that admin theme was not using cakephp 3 form helper sintax, it was html.
after i changed with Form->create() ?> Form->end() ?> it worked fine

Related

calling Https url on Http get request angularjs

I have a Https url and want to send request to get data from that URL , scenario 1:
from my browser If I hit the Url i get the response whereas from my Angularjs App I get always an error 401 , but if I hit the Api from browser I always get the correct response
for security reasons I couldn't use Url here but what I want is to:
$http({
method: "GET",
url: "https://urlAdresss/",
headers: {
"Accept-Language": "en-US, en;q=0.8",
"Content-Type": "application/json;charset=UTF-8"
},
}).then(function (_response) {
console.log(_response
}
I always get unauthorized I am network as well as On console any help will be greatly appreciated ,
but If I hit the same Url from browser I get the response It means the backend is working fine
I think I am missing something in my get request that's why getting the error
It seems a CORS (Cross-Origin Resource Sharing) issue.
In AngularJS side, you should use the following configuration in order for $http service to automatically send authorization headers to http requests.
var app = angular.module('app', [])
.config(function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
$httpProvider.defaults.withCredentials = true;
});
And in backend you should specify explicitly allowed origins (eg. http://localhost:8888).
Also, note some points from here.
If you want to allow credentials then your Access-Control-Allow-Origin must not use *.

React app using API with another origin (CORS)

I have a react app, which uses a java ee backend rest server, running on another domain. I have enabled CORS:
Access-Control-Allow-Origin : http://localhost:3000
Access-Control-Allow-Headers : origin, content-type, accept, authorization
Access-Control-Allow-Credentials : true
Access-Control-Allow-Methods : GET, POST, PUT, DELETE, OPTIONS, HEAD
Access-Control-Max-Age : 1209600
I am using react with fetch like this:
export function get(path, headers) {
return fetch(apiUrl + path, {
"metod" : "GET",
"headers" : headers,
"credentials" : "include"
})
}
My react app is running on http://localhost:3000.
When I am logging in, the server returns the Set-Cookie, but the cookie is not included in any further request to the server, unless I try to log in again. Then it is included for that specific login request.
Any suggestions?
I just want to share how I make my local development painless by this post if you are using create-react-app by just adding your main API url proxy to your package.js for example "proxy": "http://localhost:8080/API"
No need to setup CORS on your backend.
Install this.
https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?hl=es
Once installed, click on his BrowserIcon and toggle on. It is all. You will not receive more error.
EDIT. Solution for Production
If you want config it from your server (or simply not adding a browser extension, try this:)
If you are using node.js do the following: node.js server file: response.writeHead(200, { 'Content-Type': contentType, 'Access-Control-Allow-Origin': '*' })
fetch('http://ajax.googleapis.com/ajax/services/feed/load?v=‌​1.0&num=8&q=http://r‌​ss.cnn.com/rss/editi‌​on_entertainment.rss‌​?output=rss', { method: 'get', mode: 'no-cors', }).then(() => { console.log('Works!'); });
Other solution:If you are using PHP too you can add: <?php header('Access-Control-Allow-Origin: *'); ?> into your PHP File. As I see, it is not the case, so... In your server (eg: Apache) add this directive: Header set Access-Control-Allow-Origin * in Settings (as the first option).
So, I solved the problem by using another stackoverflow thread and robertklep's comment. As stated here: "When working on localhost, the cookie domain must be omitted entirely.". I implemented robertkleps idea, but did not set the domain. It resulted in a Set-Cookie like this: Set-Cookie:kek=7fukucsuji1n1ddcntc0ri4vi; Version=1; Path=/; Max-Age=100000. This works fine.
To add more on existing answers.
With react you can use "proxy" in your package.json to avoid CORS.
Basically if you need to reach localhost:8100 (your java backend) and your react app run on localhost:3000
You can set:
In your package.json
"proxy": "http://localhost:8100"
And then when you want to make a get to /hello which would be an endpoint of your java API you can do:
import axios from 'axios';
axios.get('/hello')
.then(resp => {
console.log(resp.data);
});
And it will be redirected to http://localhost:3000/hello so you will avoid CORS.

Angular with wordpress jwt auth

I'm trying to make wordpress as a backend to my angularjs app, so I'm using the plugin rest-api with the jwt-auth
so when trying to login I get the following error
XMLHttpRequest cannot load http://localhost/back/wp-json/jwt-auth/v1/token. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://imider.ma' is therefore not allowed access. The response had HTTP status code 500.
I know i have to add CROS access, but I'm not familiar with wordpress, so any help?
https://docs.google.com/document/d/17zgUHZrvL5KVG2yKQE8NWgxNZn6V08xr65DBox5WVZ0/edit?usp=sharing
here is my tutorial of how to access the api
then you can use this to get the token
$http({
method:'post',
url:'',
data: {
username: '',
password: ''
}
}).then(function(results){
console.log(results);
})
then you can use this
$http({
method:'get',
url:'',
headers: { 'Authorization': 'Bearer <myTokenId>' }
}).then(function(results){
console.log(results);
})
I created a video detailing the process of installing and setting up the plugin. If you follow the steps I outlined there you should be good.
https://youtu.be/Mp7T7x1oxDk
The idea is that you also need to modify .htaccess and wp-config.php to make the plugin work with the existing API endpoints as well.
Just by installing the plugin and adding a SECRET_KEY, used to sign the token will make the JWT setup work but it will not allow you to use the tokens generated through that API with the existing REST API endpoints.

Node/Express not finding route for Angular http json post (404)

I'm developing a new Angular client which should communicate with my Node/Express server. I'm currently trying to develop the first step aka the login. This should be an http json post. It turns out that every single time I execute that post from the client to the server, the Node/Express server doesn't find the route for my path.
On the console log of the server, for my post json request I find following stacktrace:
OPTIONS /api/auth/facebook/mobile 404 274.092 ms - 1980
Node/Express side:
My route
app.post('/api/auth/facebook/mobile', authenticationHandler.handleFacebookMobileLoginRequest);
Body parser for json is defined:
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
On the Angular client side, I do:
http({
method: 'POST',
url: 'http://192.168.1.101:3000/api/auth/facebook/mobile',
headers: { 'Content-Type': 'application/json; charset=UTF-8;' },
data: {fbToken: authResponse.accessToken}
})
.then(function (response) {
...
Fun facts:
Same route works fine when I call it from a Java app or and Android native app, like
final JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, SERVER_URL + "/api/auth/facebook/mobile", params, jsonRequestListener, errorListener);
On my Angular client, when I change data with params then it works, the route is found...but I mean that doesn't make any sense. Moreover, I've got then a problem on the Angular client side, the answer isn't processed respectively the answer never land in the .then(... function. Which again works well in other clients.
Anyone got an idea, a clue or should I call Dr. Strange?
Possible browser preflighted request CORS issue?
Try using CORS module in Node.js server:
var cors = require('cors')
app.use(cors());

grails REST API with Spring Security core and CORS plugins not working for OPTIONS http method requests

Trying to do cross-domain request [CORS] from AngularJS front-end to Grails 2.3.1 RESTful Service on other server.
AngularJS sends OPTIONS http request first for any cross-domain requests.
To support this, I added following method to my Controller that extends RestfulController
static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE", options: "OPTIONS", trace: "TRACE", head: "HEAD"]
#Secured(value=['permitAll'], httpMethod='OPTIONS')
def options() {
log.debug("i am in options method")
response.setHeader("Allow", "GET,POST,PUT,DELETE,OPTIONS,TRACE,HEAD")
return
}
For cURL command bellow, my options() method on my Controller never getting called. curl always gets 301 response.
curl -H "Origin: http://example.com" -X OPTIONS --verbose http://localhost:8080/Console/tenants/1/spaces.xml
Is this a bug in Spring Security core plugin or am I missing something?
My environment consists, Grails 2.3.1, Spring Security Core and ACL 2.0-RC1 plugins and CORS plugin 1.1.1
That's because the browser checks for cross domain requests before your action. You can do that using a servlet filter, or just use the CORS Grails plugin.
using latest CORS Grails plugin solves the problem. It includes a filter that intercept OPTIONS request and provide the response.

Resources