As a beginner to Ember.js I tried fetching some data from my Rails Api server to Ember App. My Ember App is trying to get and show the categories name served from the rails api.
I am using
Ember version: 1.13.8
node: 0.12.7
npm: 2.13.4
app/router.js
Router.map(function() {
this.resource('categories',function(){
this.resource('category',{path: '/:category_id'});
});
});
routes/categories/index.js
export default Ember.Route.extend({
model() {
return this.store.findAll('category')
}
});
app/models/category.js
export default DS.Model.extend({
name: DS.attr('string')
});
app/adapters/application.js
export default DS.JSONAPIAdapter.extend({
shouldReloadAll: function() { return true; },
namespace: 'v1',
host: 'http://ip.address-to_rails_api'
});
app/templates/categories/index.hbs
<ul>
{{#each model as |category|}}
<li>{{category.name}}</li>
{{/each}}
</ul>
Now when I visit http://ip.address-to_rails_api in my browser I get response
{"categories":[{"id":1,"name":"Entertainment"}, {"id":2,"name":"Education"}]}
but when I visit /categories in my ember app i.e. http://localhost:4200/categories
Noting is displayed in browser and I get error in ember inspector
routeName: "categories.index_error"
context: Error: Adapter operation failed
currentModel: Error: Adapter operation failed
Also the ember server console reflects error
Content Security Policy violation: {}
I also tried changing JSONAPIAdapter to RESTAdapter but it gave deprecation error. Please help me understand the problem.
Finally resolved the issue
The problem was on both parts Rails API as well as Ember App
First Error
Content Security Policy violation: {}
was removed by adding content security policy to ember app
config/environment.js
contentSecurityPolicy: {
'default-src': "'none'",
'font-src': "'self'",
'img-src': "'self'",
'media-src': "'self'",
'style-src': "'self' 'unsafe-inline'",
'script-src': "'self' 'unsafe-eval' http://ip_to_rails_api",
'connect-src': "'self' ws://ip_to_rails_api"
}
Then I got an error
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. The response had HTTP status code 404.
This error was resolved by using Cross Origin Resource Sharing or CORS on rails api end. SO that for each request the browser sends an OPTIONS request first and the server returns a response with some extra headers. The browser is then able to make the original request.
For more on CORS refer How does Access-Control-Allow-Origin header work?
Related
I am trying to use azure app insights in my react application. But when I am running this its failing to post events to azure server due to a csp error.
Refused to connect to 'https://eastus-8.in.applicationinsights.azure.com//v2/track' because it violates the document's Content Security Policy.
Refused to connect to '' because it violates the following Content Security Policy directive: "connect-src 'unsafe-inline' 'self'".
we are using these npm modules to setup insights
"#microsoft/applicationinsights-react-js": "^3.4.0",
"#microsoft/applicationinsights-web": "^2.8.9",
Below the configuration we are using:
import { ApplicationInsights } from '#microsoft/applicationinsights-web';
import { ReactPlugin } from '#microsoft/applicationinsights-react-js';
const { REACT_APP_INSIGHT_CONNECTION_STRING } = process.env;
export const reactPlugin = new ReactPlugin();
const appInsights = new ApplicationInsights({
config: {
connectionString: REACT_APP_INSIGHT_CONNECTION_STRING,
enableCorsCorrelation: true,
enableAutoRouteTracking: false,
extensions: [reactPlugin],
}
});
appInsights.loadAppInsights();
it should allow to post the events from our react app. please let me know if I am missing any configuration to fix this.
I'm having some CORS issues. In my environment I have:
Laravel project running on 127.0.0.1:8000
Vue project running on localhost:8080
This is the configuration of Vue:
const { defineConfig } = require('#vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
devServer: {
proxy: {
'/api': {
target: 'http://127.0.0.1:8000',
changeOrigin: true
},
'/sanctum': {
target: 'http://127.0.0.1:8000',
changeOrigin: true,
}
}
}
})
I'm trying to do the following requests to the Laravel server:
axios.get('sanctum/csrf-cookie').then(() => {
axios.post('api/login', {
email: email,
password: password
}).then(response => {
this.user = response.data.user
this.token = response.data.token
})
})
In the first request, the XSRF token is being set. The second request to 'api/login', however, is receiving a 302 redirection to 127.0.0.1:8000 (the /api/login route is not being considered).
The Javascript console is showing the following error:
Access to XMLHttpRequest at 'http://127.0.0.1:8000/' (redirected from 'http://localhost:8080/api/login') from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I've tried changing both client and server side configurations but I'm always going back to where I started from.
Some additional details:
if I do the login request directly toward 127.0.0.1:8000/api/login, I receive a CSRF mismatch error from Laravel (so there is not a CORS issue)
this is how the API login route is configured:
Route::post('login', '\App\Http\Controllers\Auth\LoginController#apiLogin');
I'd like to set up my Angular app to use Firebase's emulators and followed this guide to set up my app.module.ts as follows:
import { USE_EMULATOR as USE_AUTH_EMULATOR } from '#angular/fire/compat/auth';
import { USE_EMULATOR as USE_DATABASE_EMULATOR } from '#angular/fire/compat/database';
import { USE_EMULATOR as USE_FIRESTORE_EMULATOR } from '#angular/fire/compat/firestore';
#NgModule({
// ... Existing configuration
providers: [
// ... Existing Providers
{ provide: USE_AUTH_EMULATOR, useValue: environment.useEmulators ? ['http://localhost', 9099] : undefined },
{ provide: USE_DATABASE_EMULATOR, useValue: environment.useEmulators ? ['http://localhost', 9000] : undefined },
{ provide: USE_FIRESTORE_EMULATOR, useValue: environment.useEmulators ? ['http://localhost', 8080] : undefined },
]
})
export class AppModule { }
There are no errors after running firebase emulators:start as well as ng serve. If I try to log in, I get the following error in Chrome: FirebaseError: Firebase: A network AuthError (such as timeout, interrupted connection or unreachable host) has occurred. (auth/network-request-failed). There is also a failed network request: POST http://localhost/identitytoolkit.googleapis.com/v1/accounts:signUp?key=API_KEY net::ERR_CONNECTION_REFUSED
If I try the same action in FireFox, I get this error: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost/identitytoolkit.googleapis.com/v1/accounts:signUp?key=API_KEY. (Reason: CORS request did not succeed) along with the ones I get in Chrome.
The guide I was following said to use localhost instead of http://localhost though when the page loaded, I got the error FirebaseError: Firebase: Emulator URL must start with a valid scheme (http:// or https://). (auth/invalid-emulator-scheme) in the DevTools console. I'm using "#angular/fire": "^7.0.3"
What can I do to fix this issue?
I managed to solve this by downgrading to #angular/fire v6
I am calling 2 GitHub API's but i am getting above error when I am printing the response in the console. I googled the error and tried fixing it by creating proxy.json file and modifying package.json file but it doesn't fix the error.
export class HomeComponent implements OnInit {
pythonJD:any[];
javaJD:any[];
constructor(private service: GithubService) { }
ngOnInit() {
this.python()
this.java()
}
python() {
this.service.getPython().subscribe(res => {
this.pythonJD = res;
console.log(res)
});
}
java() {
this.service.getJava().subscribe(res => {
this.javaJD = res;
console.log(res)
});
}
}
export class GithubService {
constructor(private http:HttpClient) { }
getPython():Observable<any>{
return this.http.get('https://jobs.github.com/positions.json?description=python&location=new+york');
}
getJava():Observable<any>{
return this.http.get('https://jobs.github.com/positions.json?description=java&location=new+york');
}
}
CORS is fixed on the api side. https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
For security reasons, browsers restrict cross-origin HTTP requests initiated from scripts. For example, XMLHttpRequest and the Fetch API follow the same-origin policy. This means that a web application using those APIs can only request resources from the same origin the application was loaded from, unless the response from other origins includes the right CORS headers.
Since you don't control github, so you can't add the CORS header on the client side, you need to configure a proxy to fix that.
You can configure angular cli for local testing using this guide: https://juristr.com/blog/2016/11/configure-proxy-api-angular-cli/
Check also angular-cli server - how to proxy API requests to another server? for official documentation
I've upgraded an ember-cli app with a custom authenticator and authorizer for simple-auth from 0.0.40 and ember-cli-simple-auth 0.6.3 to versions 0.0.46 and 0.6.7, respectively.
Authentication works fine, but the authorize() method doesn't fire, so the security token isn't added to the header and http 401 errors are returned.
I've read elsewhere that this could be a lack of crossOriginWhitelist issue, but I have this in my index.html:
<script>
window.EmberENV = {{EMBER_ENV}};
<!-- Ember Simple Auth relies on window.ENV to read its configuration -->
window.ENV = window.EmberENV;
window.ENV['simple-auth'] = {
authorizer: 'authorizer:custom',
crossOriginWhitelist: window.EmberENV.APP.crossOriginWhitelist
};
</script>
which seems fine to me.
I can eliminate the 401 error by adding this to the ajax call in my beforeModel() authorization check:
beforeSend: function (request)
{
request.setRequestHeader('Authorization', 'Bearer ' + self.get('session.token'));
},
but that ain't right, of course; it's just a band-aid.
Anyone have any ideas?
Thanks,
BillyB
I found the problem.
The only changes I made other than upgrading the ember-cli version was to switch from ember-simple-auth to ember-cli-simple-auth, the Ember Simple Auth base library packaged as an Ember CLI Addon.
The latter accepts its configuration in ember-cli's environment.js instead of in an inline script in index.html, as I had done above. This worked:
ENV['simple-auth'] = {
authenticationRoute: 'login',
routeAfterAuthentication: 'index',
routeIfAlreadyAuthenticated: 'index',
authorizer: 'authorizer:custom',
crossOriginWhitelist: ENV.APP.crossOriginWhitelist
Note to folks at simple-auth: this was not well-documented, or at least I missed it.
-BillyB