CORS header ‘Access-Control-Allow-Origin’ missing Laravel 5.4 - javascript

I have a problem with CORS using javascript.
Cross-Origin Request Blocked: The Same Origin Policy disallows reading
the remote resource at http://openexchangerates.org/latest.json.
(Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
To fix this issue I install laravel-cors package
But it didn't help at all. Can some one advice me how to fix this problem? How can I debug it to see where is the problem and why this package not working?
This is my code.
In \Http\Kernel.php
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\Barryvdh\Cors\HandleCors::class,
];
In \config\app.php
'providers' => [
Barryvdh\Cors\ServiceProvider::class,
],
In \config\cors.php
<?php
return [
/*
|--------------------------------------------------------------------------
| Laravel CORS
|--------------------------------------------------------------------------
|
| allowedOrigins, allowedHeaders and allowedMethods can be set to array('*')
| to accept any value.
|
*/
'supportsCredentials' => false,
'allowedOrigins' => ['*'],
'allowedHeaders' => ['*'],
'allowedMethods' => ['*'],
'exposedHeaders' => [],
'maxAge' => 0,
];
End my js:
$(document).ready(function(){
fx.base = "EUR";
fx.settings = {
from : "EUR"
};
var amount = 9.99; //in SolidShops, you could use: {{ product.price }}
// Load exchange rates data via the cross-domain/AJAX proxy:
$.getJSON(
'http://openexchangerates.org/latest.json',
function(data) {
// Check money.js has finished loading:
if ( typeof fx !== "undefined" && fx.rates ) {
fx.rates = data.rates;
fx.base = data.base;
} else {
// If not, apply to fxSetup global:
var fxSetup = {
rates : data.rates,
base : data.base
}
}
// now that we have exchange rates, add a few to our page
var USD = fx.convert(amount, {to: "USD"}); //13.22784197768393
var GBP = fx.convert(amount, {to: "GBP"}); //8.567532636985659
var JPY = fx.convert(amount, {to: "JPY"}); //1028.1670562349989
// we can now use the accounting.js library to format the numbers properly
USD = accounting.formatMoney(USD, "$ ", 2, ",", ".");
GBP = accounting.formatMoney(GBP, "£ ", 2, ",", ".");
JPY = accounting.formatMoney(JPY, "¥ ", 2, ",", ".");
$("ul.currencies").append("<li>USD estimate: " + USD + "</li>");
$("ul.currencies").append("<li>GBP estimate: " + GBP + "</li>");
$("ul.currencies").append("<li>JPY estimate: " + JPY + "</li>");
}
);
});

You need to instead use the URL https://openexchangerates.org/api/latest.json
The error message cited in the question indicates that the openexchangerates.org server isn’t sending the Access-Control-Allow-Origin response header back to your code when your code makes a request to the URL http://openexchangerates.org/latest.json.
So it doesn’t matter what CORS config you do on your own server backend where your own code is being served from. The problem you ran into was only because of the openexchangerates.org not sending back that Access-Control-Allow-Origin response header.
But if you instead use the right URL—https://openexchangerates.org/api/latest.json—then that server will send back the Access-Control-Allow-Origin header in its response, and you won’t get that “CORS header ‘Access-Control-Allow-Origin' missing” error message any longer.

Related

Google gmail api list messages by labelId error 400

I am working on a domain-wide delegation app to pull attachments from a user's email with a specific label. When trying to get their messages, I get this exception:
{
error={
code=400.0,
message='raw' RFC822 payload message string or uploading message via /upload/* URL required,
status=INVALID_ARGUMENT,
errors=[
{reason=invalidArgument, message='raw' RFC822 payload message string or uploading message via /upload/* URL required, domain=global}
]
}
}
The Gmail API documentation suggests to me that the labelIds property is an array of label ids.
From Resolve errors documentation these would cause a 400 exception.
A required field or parameter hasn't been provided.
The value supplied or a combination of provided fields is invalid.
Invalid attachment.
I don't think its 1, no parameter is mandatory based on the docs.
Number 3 is out because theres no attachment.
So thats leaves 2. what field am I messing up?
Things I don't know: 'raw' and RFC822 from the following exception
Here is the exception "message='raw' RFC822 payload message string or uploading message via /upload/* URL required"
function getMessages(oAuth,userEmail,labels){
let labels = ['Label_718766733436502667']
if (oAuth.hasAccess()) {
let url = 'https://gmail.googleapis.com/gmail/v1/users/' + userEmail + '/messages'
let token = service.getAccessToken();
let payload = JSON.stringify({labelIds:labels})
let options = {
headers: {
Authorization: "Bearer " + token,
"content-type": "application/json"
},
method: "GET",
payload:payload,
//muteHttpExceptions: true
};
let response = UrlFetchApp.fetch(url, options);
//Logger.log(response.getContentText());
let result = JSON.parse(response.getContentText());
Logger.log(result)
return result
//Logger.log(JSON.stringify(result, null, 2));
} else {
Logger.log(service.getLastError());
}
}

Django - csrf cookie not set

I've been trying for hours to send a POST request to an endpoint in my Django application from my separated VueJS frontend using Axios. The problem with my code is that whatever i try i will always get Forbidden (CSRF cookie not set.), and i can't use #crsf_exempt.
I tried every possible solution i found, from changing headers names in my Axios request to setting CSRF_COOKIE_SECURE to False, nothing seems to solve this problem.
Here is my request:
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
console.log(cookieValue)
return cookieValue;
}
function req(){
this.csrf_token = getCookie('csrftoken')
axios({
method: 'post',
url: 'http://127.0.0.1:8000/backend/testreq/',
data: {
//Some data here
},
headers: {'Content-Type': 'application/json', 'X-CSRFToken': this.csrf_ftoken }
}).then(function (response) {
console.log(response)
}).catch(function (error) {
console.log(error)
});
},
The token is being sent but the outcome is always the same. The Django app is using Django-Rest-Framework too, i don't know if that's the problem.
Here is some of my settings.py (for development):
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_HEADERS = list(default_headers) + [
'xsrfheadername',
'xsrfcookiename',
'content-type',
'csrftoken',
'x-csrftoken',
'X-CSRFTOKEN',
]
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_WHITELIST = [
"http://localhost:8080",
"http://127.0.0.1:8080",
"http://localhost:8000",
"http://127.0.0.1:8000",
]
CORS_ALLOWED_ORIGINS = [
"http://localhost:8080",
"http://127.0.0.1:8080",
"http://localhost:8000",
"http://127.0.0.1:8000",
]
CSRF_TRUSTED_ORIGINS = [
"http://localhost:8080",
"http://127.0.0.1:8080",
"http://localhost:8000",
"http://127.0.0.1:8000",
]
SESSION_COOKIE_SAMESITE = None
CSRF_COOKIE_SAMESITE = None
CSRF_COOKIE_SECURE = False
CSRF_COOKIE_HTTPONLY = False
SESSION_COOKIE_SECURE = False
I don't know what else can i try to solve this problem, any advice is appreciated
The Default Authentication Scheme in Django Rest Framework is
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
]
}
Session Authentication requires a CSRF Token when you make POST requests unless exempted using #csrf_exempt
CSRF_COOKIE_SECURE in Django only ensures that CSRF Tokens are sent via HTTPS
To Fix Your Issue, you can change DEFAULT_AUTHENTICATION_CLASSES from the default to
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
]
}
Once you switch to TokenAuthentication you'll have to exchange the user's credentials for an Auth token and use that Token For Subsequent requests
Django Rest Framework's guide on Token Authentication
You can also take a look at this SO answer here to use #csrf_exempt on class based views
I suppose it's a problem caused by 'cross-domain', you cannot set cookie or store it in browser generated by backend localhost:8000 through frontend localhost:8080. If you want to store or modify cookie you can only access localhost:8000.
You can use Nginx as reverse proxy to solve the problem, Here is the video for details
https://youtube.com/watch?v=VeDms9GPaLw

ASP.NET Core 3.1 CORS configuration gone wrong

The application is configured to use HTTPS. We want to be able to make calls from the client to a printer on their local network that exposes a simple api that uses HTTP. So from our javascript code we do a POST with a "text/plain" payload to send commands to the printer. When we send this request we get the following error.
jquery-3.3.1.min.js:2 Mixed Content: The page at 'https://...' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://.../pstprnt'. This request has been blocked; the content must be served over HTTPS.
Is there a way to configure CORS in such a way that only this traffic from and to a printer can be done using HTTP while the rest of the application uses HTTPS, without specifying the target IN startup.cs ? ( this is because the printers should be able to be expanded at runtime, so basically just 'allow all orgins', so that its not restricted to the ones specified in Startup.cs)
I have tried multiple guides online, but I'm guessing there is something wrong with our Startup.cs file structure.
The request to the printer looks like this:
$.ajax({
type: "POST",
url: "http://<printer-ip>/pstprnt",
data: 'some ZPL',
contentType: 'text/plain'
}).done((res) => {
console.log("second success");
}).fail((e) => {
alert(e);
})
Here is a snippet our Startup file.
CONFIGURE SERVICES
public void ConfigureServices(IServiceCollection services)
{
// Add Cors
services.AddCors();
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
/* (Verification/password reset) email sender */
//services.AddTransient<IEmailSender, EmailSender>();
//services.Configure<AuthMessageSenderOptions>(Configuration);
Task.Run(() => {
var options = new DbContextOptionsBuilder<ApplicationDbContext>().UseSqlServer(Configuration.GetConnectionString("DefaultConnection")).Options;
using (var dbContext = new ApplicationDbContext(options)) {
var model = dbContext.AankoopProduct;
}
});
services.AddLocalization();
/*
I commented this out because I am using UseEndpoints, Am I doing this correctly?
services.AddMvc()
.AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
.AddDataAnnotationsLocalization().AddNewtonsoftJson(options =>
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
*/
services.AddIdentity<Gebruiker, IdentityRole>(options =>
{
options.Lockout.MaxFailedAccessAttempts = 5;
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(15);
options.SignIn.RequireConfirmedEmail = true;
}).AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.Configure<IdentityOptions>(options =>
{
// Password settings.
options.Password.RequireDigit = true;
options.Password.RequireLowercase = true;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = true;
options.Password.RequiredLength = 6;
options.Password.RequiredUniqueChars = 1;
});
services.AddControllersWithViews().AddNewtonsoftJson(options =>
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
// .cshtml views & .razor components
services.AddRazorPages();
//SignalR for Websockets
services.AddSignalR();
// reload views after changing JS
#if DEBUG
var mvcBuilder = services.AddControllersWithViews();
mvcBuilder.AddRazorRuntimeCompilation();
#endif
services.ConfigureApplicationCookie(opts => opts.LoginPath = "/Account/Login");
/* Breadcrumbs */
services.AddBreadcrumbs(GetType().Assembly, options =>
{
options.TagName = "nav";
options.TagClasses = "";
options.OlClasses = "breadcrumb breadcrumb--transparent m-0";
options.LiClasses = "breadcrumb-item";
options.ActiveLiClasses = "breadcrumb-item active";
//options.SeparatorElement = "<li class=\"separator\">/</li>";
});
/* Repositories */
services.RegisterRepositories();
services.AddSession();
}
CONFIGURE
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IVerkoopProductXMLRepository rep)
{
//app.ApplicationServices.GetService<IInkomendeBestellingTrackerSingleton>();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
#region Auth
var supportedCultures = new[]
{
new CultureInfo("nl-BE")
};
app.UseRequestLocalization(new RequestLocalizationOptions
{
DefaultRequestCulture = new RequestCulture("nl-BE"),
// Formatting numbers, dates, etc.
SupportedCultures = supportedCultures,
// UI strings that we have localized.
SupportedUICultures = supportedCultures
});
var cultureInfo = new CultureInfo("nl-BE");
cultureInfo.NumberFormat.CurrencySymbol = "€";
cultureInfo.NumberFormat.NumberDecimalSeparator = ".";
CultureInfo.DefaultThreadCurrentCulture = cultureInfo;
CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("nl-BE");
Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("nl-BE");
// To configure external authentication,
// see: http://go.microsoft.com/fwlink/?LinkID=532715
#endregion
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseStatusCodePages();
app.UseRouting();
app.UseSession();
// Enable Cors
app.UseCors();
/*
I commented this out because I am using UseEndpoints() , Am I doing this correctly?
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=UserSelection}/{id?}");
});
*/
app.UseCookiePolicy();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints => {
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Account}/{action=Login}/{id?}");
});
}
This doesn't relate to your ASP.NET CORS configuration, because you're making a request directly from the client (the browser) to the printer; CORS would come into play if you were making cross-domain requests to the ASP.NET API.
What you could do is make the request to the printer from the server, instead, assuming your network topology permits it. Make an AJAX request from your JS to a new endpoint on the server, which then makes a plain HTTP request to the printer.

graphql query to json query

Given this GraphQL example, how can I in Javascript do a similar request with JSON?
Using GraphQL the query in the example is:
{
trip(
from: {place: "NSR:StopPlace:5533" },
to: {place:"NSR:StopPlace:5532"}
)
{
tripPatterns{duration}
}
}
According to the documentation the URL to query is https://api.entur.io/journey-planner/v2/graphql .
Here is what I tried in Javascript:
var url = "https://api.entur.io/journey-planner/v2/graphql";
var tripquery =
{
trip:
{
__args: {
from : {place :"NSR:StopPlace:5533" },
to : {place :"NSR:StopPlace:5532" }
},
tripPatterns: {
duration : true
}
}
};
function jsonQuery(){
var qry = JSON.stringify(tripquery);
var url_qry = url + "?query=" + qry;
var xhttp = new XMLHttpRequest();
xhttp.open("POST", url_qry, true);
xhttp.setRequestHeader("Content-Type", "application/json");
xhttp.onreadystatechange = function(){
console.log("onreadystatechange");
if(xhttp.readyState === 4 && xhttp.status === 200){
console.log("json-query-OK");
console.log(xhttp.responseText);
}
else{
console.log("xhttp.status : " + xhttp.status);
console.log("xhttp.statusText : " + xhttp.statusText);
console.log("xhttp.readyState : " + xhttp.readyState);
console.log("xhttp.responseType: " + xhttp.responseType);
console.log("xhttp.responseText: " + xhttp.responseText);
console.log("xhttp.responseURL : " + xhttp.responseURL);
console.log("json-not-ok");
}
};
xhttp.send();
console.log("query sent");
}
The code above will result in this output in the console:
query sent
api.entur.io/journey-planner/v2/graphql?query={%22trip%22:{%22__args%22:{%22from%22:{%22place%22:%22NSR:StopPlace:5533%22},%22to%22:{%22place%22:%22NSR:StopPlace:5532%22}},%22tripPatterns%22:{%22duration%22:true}}}:1 POST https://api.entur.io/journey-planner/v2/graphql?query={%22trip%22:{%22__args%22:{%22from%22:{%22place%22:%22NSR:StopPlace:5533%22},%22to%22:{%22place%22:%22NSR:StopPlace:5532%22}},%22tripPatterns%22:{%22duration%22:true}}} 400 (Bad Request)
query.js:29 onreadystatechange
query.js:35 xhttp.status : 400
query.js:36 xhttp.statusText : Bad Request
query.js:37 xhttp.readyState : 2
query.js:38 xhttp.responseType:
query.js:39 xhttp.responseText:
query.js:40 xhttp.responseURL : https://api.entur.io/journey-planner/v2/graphql?query={%22trip%22:{%22__args%22:{%22from%22:{%22place%22:%22NSR:StopPlace:5533%22},%22to%22:{%22place%22:%22NSR:StopPlace:5532%22}},%22tripPatterns%22:{%22duration%22:true}}}
query.js:41 json-not-ok
query.js:29 onreadystatechange
query.js:35 xhttp.status : 400
query.js:36 xhttp.statusText : Bad Request
query.js:37 xhttp.readyState : 3
query.js:38 xhttp.responseType:
query.js:39 xhttp.responseText: No query found in body
query.js:40 xhttp.responseURL : https://api.entur.io/journey-planner/v2/graphql?query={%22trip%22:{%22__args%22:{%22from%22:{%22place%22:%22NSR:StopPlace:5533%22},%22to%22:{%22place%22:%22NSR:StopPlace:5532%22}},%22tripPatterns%22:{%22duration%22:true}}}
query.js:41 json-not-ok
query.js:29 onreadystatechange
query.js:35 xhttp.status : 400
query.js:36 xhttp.statusText : Bad Request
query.js:37 xhttp.readyState : 4
query.js:38 xhttp.responseType:
query.js:39 xhttp.responseText: No query found in body
query.js:40 xhttp.responseURL : https://api.entur.io/journey-planner/v2/graphql?query={%22trip%22:{%22__args%22:{%22from%22:{%22place%22:%22NSR:StopPlace:5533%22},%22to%22:{%22place%22:%22NSR:StopPlace:5532%22}},%22tripPatterns%22:{%22duration%22:true}}}
query.js:41 json-not-ok
The __args in the Json object is something I got from an example online, but I haven't really understood it.
Maybe I'm not sure what exactly to search for, but I can't find some good explanation of how to translate this GraphQL query to a JSON object.
I had the same problem and I did it like this:
{
c_con_tic_PTF(dz: CR, docmanId: 123) {
docmanId
dz
data
}
}
I tried sending this request as curl command in OS X How to use CURL in OS X:
curl \
-X POST \
-H "Content-Type: application/json" \
--data '{ "query": "{ c_con_tic_PTF(docmanId: 123, dz: CR) { docmanId, dz, data }}" }' \
*my-graphicQL endpoint url*
And I got the response I wanted.
So you want to make something like this from your graphQL query:
{ "query": "{ cz_atlascon_etic_PTF(docmanId: 123, dz: CR) { docmanId, dz, data }}" }
And now just send request with JS.
If it helps you in any way, this is how my request looked in Java:
HttpRequest mainRequest =
HttpRequest.newBuilder()
.uri(URI.create("my graphQL endpoint"))
.POST(HttpRequest.BodyPublishers.ofString("{ \"query\": \"{ c_con_tic_PTF(docmanId: 123, dz: CR) { docmanId, dz, data }}\" }"))
.build();
One way to do it in Javascript is using the fetch api. Something like this is how I've done it in the past. You can test it out by copying the code below and then pasting it into Chrome Dev Tools and running it.
async function makeGraphQlQuery(urlToResource) {
const queryObject = {
query:
'{ trip( from: {place: "NSR:StopPlace:5533" }, to: {place:"NSR:StopPlace:5532"}) {tripPatterns{duration}} }',
};
const response = await fetch(urlToResource, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(queryObject),
});
const json = response.json();
return json;
}
async function sendAsync() {
const res = await makeGraphQlQuery('https://api.entur.io/journey-planner/v2/graphql');
console.log(res);
}
sendAsync().catch(err => console.log('Error in query', err));

Angular fetch vine thumbnail

I attempt to fetch vine thumbnail following their doc with the following code:
<!-- language: lang-js -->
var onGetVineThumbnailSuccess = function( videoUrl ) {
return function( response ) {
var args = { videoUrl: videoUrl };
args.thumbnailUrl = response['thumbnail_url']; // jshint ignore:line
$rootScope.$broadcast( 'event:onGetVineThumbnailSuccess', args);
};
};
var getVineThumbnail = function ( videoUrl ) {
$http
.get( 'https://vine.co/oembed.json?url=' + encodeURIComponent( videoUrl ) )
.then( onGetVineThumbnailSuccess( videoUrl ) );
};
but in the console I've this error:
XMLHttpRequest cannot load https://vine.co/oembed.json?url=https%3A%2F%2Fvine.co%2Fv%2FeV1mMuab7Mp. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9000' is therefore not allowed access.
By the way this link: https://vine.co/oembed.json?url=https%3A%2F%2Fvine.co%2Fv%2FeV1mMuab7Mp works. If I put directly to browser's url bar. I obtain this JSON:
{
"version": 1.0,
"type": "video",
"cache_age": 3153600000,
"provider_name": "Vine",
"provider_url": "https://vine.co/",
"author_name": "Evengelia",
"author_url": "https://vine.co/u/1204040590484971520",
"title": "Everything was beautiful on this day. #6secondsofcalm",
"thumbnail_url": "https://v.cdn.vine.co/r/videos/59734161E81269170683200901120_45a46e319ea.1.1.8399287741149600271.mp4.jpg?versionId=tc3t.oqGtjpJNlOX1AeM1CAnWONhbRbQ",
"thumbnail_width": 480,
"thumbnail_height": 480,
"html": "<iframe class=\"vine-embed\" src=\"https://vine.co/v/eV1mMuab7Mp/embed/simple\" width=\"600\" height=\"600\" frameborder=\"0\"><\/iframe><script async src=\"//platform.vine.co/static/scripts/embed.js\"><\/script>",
"width": 600,
"height": 600
}
Sounds as CORS issue. But as I've no control on Vine, how should I call this service?
Access-Control-Allow-Origin is set on the response from server, not on client request to allow clients from different origins to have access to the response.
In your case, http://www.vine.co/ does not allow your origin to have access to the response. Therefore you cannot read it.
For more information about CORS: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
But, The Chrome Webstore has an extension that adds the 'Access-Control-Allow-Origin' header for you when there is an asynchronous call in the page that tries to access a different host than yours.
The name of the extension is: "Allow-Control-Allow-Origin: *" and this is the link: https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi

Categories

Resources