I have an app: Django/python backend and react frontend. Both parts were separately deployed with heroku: myapp-backend.herokuapp.com and myapp-frontend.herokuapp.com. I'm trying to get data from myapp-backend:
axios
.get("https://myapp-backend.herokuapp.com/api/spots/1")
but get two errors:
Access to XMLHttpRequest at 'https://myapp-backend.herokuapp.com/api/spots/1' from origin 'https://myapp-frontend.herokuapp.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
and
Error: Network Error
at createError (createError.js:17)
at XMLHttpRequest.handleError (xhr.js:80)
If I run myapp-frontend locally and try get data from myapp-backend.herokuapp.com - everything is ok. Also, part of settings inside backend:
INSTALLED_APPS = [
...
'corsheaders',
'rest_framework',
...
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ALLOWED_HOSTS = ['myapp-backend.herokuapp.com','myapp-frontend.herokuapp.com','127.0.0.1','localhost']
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_WHITELIST = (
'https://myapp-frontend.herokuapp.com',
'http://localhost:3000',
)
CORS_ALLOW_METHODS = [
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
]
CORS_ALLOW_HEADERS = [
'accept',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
]
I'm a little bit stuck on this, help! ))
Related
I host my code on digitalocean
Frontend use Nuxt js and Backend use Laravel
I test api using postman backend api ok
Error: strict-origin-when-cross-origin
modules: [
// https://go.nuxtjs.dev/axios
'#nuxtjs/axios',
'#nuxtjs/sitemap',
'#nuxtjs/proxy',
],
axios: {
proxy: true,
prefix: 'http://api.mydomain.com/api'
},
proxy: {
'/api/': 'http://api.mydomain.com/api',
},
Laravel sanctum has been a bit of a headache for me as i have spent hours trying to figure out why sanctum/csrf-cookie route returns no content. initially the same route return 404 not found but after adding 'prefix' => 'api/sanctum' config/sanctum.php it seems to work except that it outputs nothing and no cookie is set in my browser.
Here are some of my codes
.env
SANCTUM_STATEFUL_DOMAINS=localhost:8080
SPA_URL=http://localhost:8080
SESSION_DOMAIN=localhost
--config/cors.php
'paths' => [
'api/*',
'login',
'logout',
'register',
'user/password',
'forgot-password',
'reset-password',
'sanctum/csrf-cookie',
'user/profile-information',
'email/verification-notification',
],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => true,
axios
export const authClient = axios.create({
baseURL: process.env.VUE_APP_API_URL,
withCredentials: true, // required to handle the CSRF token
});
and having done all of that, if i tried to generate a token using
axios.get('/sanctum/csrf-cookie').then(response => {
// Login...
});
i get 204 no content response
i have also added the api middleware in kernel.php as instructed in the doucmentation but still wont set the cookie. and when i try to make request to another route protected by sanctum i 419 token mismatch.
i have also run a fresh installation of laravel, php artisan optimize, cleared my brower history, checked the endpoints in postman but still thesame 204 and 419 exceptions
I was struggling with the same issue for days and then founded a way that worked.
so :
The '/sanctum/csrf-cookie' route return a 204 response when successfull, the then you have to send your post request with credentials. i used to get a 419 reponse status.
so after followed laravel docs here is what i added :
SPA
make sure you set the withCredentials header to true
API
.env
SESSION_DRIVER=cookie
SESSION_DOMAIN='.localhost'
SANCTUM_STATEFUL_DOMAINS='localhost,127.0.0.1'
.kernel.php
add in your middleware array : \Illuminate\Session\Middleware\StartSession::class
Hey I don't know whether you've found the answer or not but that request meant to have empty response body. Your CSRF token is available in the header of the response ;D
From HTTP Specification:
The HTTP 204 No Content success status response code indicates that a request has succeeded, but that the client doesn't need to navigate away from its current page. This might be used, for example, when implementing "save and continue editing" functionality for a wiki site.
According to specification 204 is the exptected response from server.
You can insert in bootstrap.js file
import axios from 'axios';
window._ = _;
window.axios = axios;
window.axios.defaults.baseURL = "/api/";
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
I am installing the old project, which is made by Nuxt.js (frontend) and Laravel (backend) on my local.
Access to XMLHttpRequest at 'http://localhost:8000/api/user' from origin 'http://127.0.0.1:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
This is the issue that I faced to run the project.
Frontend configuration for the request(nuxt nuxt.config.js).
user: {
url: '/api/user',
method: 'get',
propertyName: false,
withCredentials: true,
headers: {
X-Requested-With': 'XMLHttpRequest',
Content-Type': 'application/json'
}
}
Backend configuration (Laravel config/cors.php)
'paths' => ['api/*'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => true,
I tried to find the solution by googling but I didn't find the correct solution.
withCredetials is true
CORS: credentials mode is 'include'
The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'
So, I want someone to help me in this field.
Try this way in your laravel app:
php artisan serve --host YOUR_LOCAL_IP
YOUR_LOCAL_IP is your ip that can access with ifconfig command in linux and ipconfig in windows.
Finally you should request to YOUR_LOCAL_IP:PORT/api
cors-headers to enable the cors on my django server. my setting.py is like this.
CORS_ORIGIN_ALLOW_ALL= True
CORS_ALLOW_CREDENTIALS = True
also i have added corsheaders to the INSTALLED_APPS and my MIDDLEWARE is like this
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'corsheaders.middleware.CorsMiddleware',
].
i have set a very simple view that looks like this.
def get(self, request):
response = HttpResponse("hi")
response['Set-Cookie'] = ('food=bread; Path=/; max_age=10000')
print(response._headers)
return response
on the console the headers is like this.
{'set-cookie': ('Set-Cookie', 'food=bread; drink=water; Path=/; max_age=10000'), 'content-type': ('Content-Type', 'text/html; charset=utf-8')}
when i call my api in browser cookie is set and everything is ok but when i use axios for ajax in the body of response there is nothing that is similar to my cookie.
my javasctipt code i like this.
axios.get('http://37.130.202.188:13434/users/test/',
{withCredentials: true,
})
.then(function (response) {
console.log(response);
});
and i run my server with this command
python manage.py runserver
every response to this headache would be very appreciated.
I find the answer. Exactly like this question, the cookies that are set in the headers of a http response are not accessible in Javascript and they get saved in the browser automatically.
I'm trying to create a SabreDAV-Server in a Laravel Route. The following Code shows that I tried:
Illuminate\Routing\Router::$verbs = [
'GET',
'HEAD',
'POST',
'PUT',
'PATCH',
'DELETE',
'PROPFIND',
'PROPPATCH',
'MKCOL',
'COPY',
'MOVE',
'LOCK',
'UNLOCK'
];
Route::match(['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'PATCH', 'PROPFIND', 'PROPPATCH', 'MKCOL', 'COPY', 'MOVE', 'LOCK', 'UNLOCK'], 'carddav{test}', function()
{
date_default_timezone_set('Europe/Berlin');
$baseUri = '/carddav';
$pdo = new PDO('mysql:host=localhost;dbname=dav', 'root', 'root');
$pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
$authBackend = new \Sabre\DAV\Auth\Backend\PDO($pdo);
$principalBackend = new \Sabre\DAVACL\PrincipalBackend\PDO($pdo);
$carddavBackend = new \Sabre\CardDAV\Backend\PDO($pdo);
$nodes = [
new \Sabre\DAVACL\PrincipalCollection($principalBackend),
new \Sabre\CardDAV\AddressBookRoot($principalBackend, $carddavBackend)
];
$server = new \Sabre\DAV\Server($nodes);
$server->setBaseUri($baseUri);
$server->addPlugin(new \Sabre\DAV\Auth\Plugin($authBackend, 'SabreDAV'));
$server->addPlugin(new \Sabre\DAV\Browser\Plugin());
$server->addPlugin(new \Sabre\CardDAV\Plugin());
$server->addPlugin(new \Sabre\DAVACL\Plugin());
$server->addPlugin(new \Sabre\DAV\Sync\Plugin());
$server->exec();
})->where('path', '(.)*';
But if I try to call it in the Browser there is an error:
<?xml version="1.0" encoding="utf-8"?>
<d:error xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns">
<s:sabredav-version>2.0.4</s:sabredav-version>
<s:exception>Sabre\DAV\Exception\NotAuthenticated</s:exception>
<s:message>No digest authentication headers were found</s:message>
</d:error>
There was no authentication prompt.
If I try to connect from Evolution there was the message: "Method Not Allowed".
Has someone any idea what the problem is?
Thanks,
pepe
The problem is the sent HTTP status code. No matter the response from SabreDAV, the Laravel router always sets the HTTP status code to 200, so no CardDAV client will ever know they have to authorize requests – ignoring the Basic Auth Challenge.
My solution might not be the most elegant one, but it is working. Just wrap the $server->exec() in ob_start() and ob_end() tags and output the content with a real Laravel response:
ob_start();
$server->exec();
$status = $server->httpResponse->getStatus();
$content = ob_get_contents();
ob_end_clean();
return response($content, $status);
General guidance:
Use "postman" (Google Chrome App) to test requests, you'll see they are working when sending authorization headers upfront
Use a web debugging proxy like "Charles" to monitor actual request and response bodies