CORS - OPTIONS ... 404 (not found) - node.js

Hi I'm having a problem with CORS.
GENERAL STRUCTURE:
Angular 4 sends data of a Form to my api.
Function saveForm() is executed when I send information about form contact.
app.component.ts
saveForm() {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
let requestOptions = new RequestOptions({ headers: headers });
// Encode JSON as string to exchange data to web server.
this.data = JSON.stringify(this.myContact);
this.http.post('https://pablocordovaupdated.herokuapp.com/api', this.data, requestOptions).subscribe(res => {
let result = res.json();
if(result['result'] == 'success') {
this.successMessage = true;
}
}
);
}
Here is the root of problem, because I'm using POST and Content-Type->application/json to send my data and by definition It gives me a problem with CORS - preflighted request, here more definition: Link about preflighted request
This meaning that before angular 4 sends the data to the server, this asks to server if it is available to receive my data with the verb OPTION, if the response of server is OK then angular 4 sends the data of form.
PROBLEM:
In console I always get this error message:
OPTIONS https://pablocordovaupdated.herokuapp.com/api 404 (Not Found)
XMLHttpRequest cannot load
https://pablocordovaupdated.herokuapp.com/api. Response to preflight
request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'https://pablocordova.herokuapp.com' is therefore not
allowed access. The response had HTTP status code 404.
XHR failed loading: POST
"https://pablocordovaupdated.herokuapp.com/api".
ERROR Response {_body: ProgressEvent, status: 0, ok: false,
statusText: "", headers: Headers…}
WHAT I TRIED:
so far, I understand that problem is because https://pablocordovaupdated.herokuapp.com/api doesn't return answer for verb OPTIONS
then I tried to resolve this of 2 ways:
Using cors package CORS package
I configured according documentation.
var express = require('express');
var cors = require('cors');
...
var app = express();
...
app.options('/api', cors());
app.post('/api', cors(), function(req, res, next) {
// Proccess to send this data via email
// and also save in data base(only for learning)
});
But I get in console the same error.
Configuring headers manually by Discussion StackOverFlow or Discussion Github
That code is inserted inside every route that I want to write the headers, in my case:
app.post('/api', function(req, res, next) {
if (req.method === 'OPTIONS') {
console.log('!OPTIONS');
var headers = {};
// IE8 does not allow domains to be specified, just the *
// headers["Access-Control-Allow-Origin"] = req.headers.origin;
headers["Access-Control-Allow-Origin"] = "*";
headers["Access-Control-Allow-Methods"] = "POST, GET, PUT, DELETE, OPTIONS";
headers["Access-Control-Allow-Credentials"] = false;
headers["Access-Control-Max-Age"] = '86400'; // 24 hours
headers["Access-Control-Allow-Headers"] = "X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept";
res.writeHead(200, headers);
res.end();
} else {
// Process to send this data via email
// and also save in data base(only for learning)
}
});
Here the problem is that never execute console.log('!OPTIONS');
Here also I tried simply:
app.post('/api', function(req, res, next) {
console.log('!I AM YOUR FATHER');
...
});
but never is printed.
Note: I tried to see this message with heroku logs because the whole page is in Heroku.
But also doing this I get the same error.
MORE INFORMATION:
When the .../api is called, I have this headers
**GENERAL**:
Request URL:https://pablocordovaupdated.herokuapp.com/api
Request Method:OPTIONS
Status Code:404 Not Found
Remote Address:23.21.185.158:443
Referrer Policy:no-referrer-when-downgrade
**RESPONSE HEADERS**:
HTTP/1.1 404 Not Found
Connection: keep-alive
Server: Cowboy
Date: Wed, 10 May 2017 04:14:45 GMT
Content-Length: 494
Content-Type: text/html; charset=utf-8
Cache-Control: no-cache, no-store
**REQUEST HEADERS**:
OPTIONS /api HTTP/1.1
Host: pablocordovaupdated.herokuapp.com
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Access-Control-Request-Method: POST
Origin: https://pablocordova.herokuapp.com
User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36
Access-Control-Request-Headers: content-type
Accept: */*
Referer: https://pablocordova.herokuapp.com/
Accept-Encoding: gzip, deflate, sdch, br
Accept-Language: es-ES,es;q=0.8
QUESTION:
That is my true problem or I am understanding bad? and/or
What can I do to solve that problem? and/or
Any advices?
Thanks.

The problem seems to be: https://pablocordovaupdated.herokuapp.com/api always returns 404:
$ curl -i https://pablocordovaupdated.herokuapp.com/api
HTTP/1.1 404 Not Found
That is, the server isn’t doing anything special/different for the OPTIONS request — instead all requests are just hitting that 404.
app.post('/api', function(req, res, next) {
console.log('!I AM YOUR FATHER');
...
});
I’m not super clear on how Express handles this case, but it may be that must configure it to send some kind of response for that route — not just a console.log on the server side.
When I look at the content of https://pablocordovaupdated.herokuapp.com/api what I see is just a generic Heroku 404 page — so it’s not being served from your app but instead falling back to being served by Heroku. For example, the contents of that 404 page have this:
<iframe src="//www.herokucdn.com/error-pages/no-such-app.html"></iframe>
That is, it appears to be that request for that URL are never getting handled as expected by your app code at all under any circumstances. So it seems like that’s what you need to fix first.

Related

Express/Nodejs received undefined json from angular using post method

What I've done: I tried to post json from angular to nodejs but it failed. I tried to search for solution of "undefined post nodejs json" and "options instead of post", and changed my header to exclude the [option], also tried to parse the json data I tried to set, but nothing is useful.
The problem: In the angular code below, I did not get response, there was no output of the "console.log()", I wonder what is wrong. And the json.body I reuqired in app.js returns "undefined"
I checked the browser, first it sends [options] request and gets 200OK, but next when it sends [post], but no status is returned :
OPTIONS /api/postData HTTP/1.1
Host: 127.0.0.1:3000
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:94.0) Gecko/20100101 Firefox/94.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type
Referer: http://127.0.0.1:4200/
Origin: http://127.0.0.1:4200
Connection: keep-alive
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
POST http://127.0.0.1:3000/api/postData
Host: 127.0.0.1:3000
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:94.0) Gecko/20100101 Firefox/94.0
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/json
Content-Length: 27
Origin: http://127.0.0.1:4200
Connection: keep-alive
Referer: http://127.0.0.1:4200/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
Is there any mistake in the code?
angular code: component.ts
this.http.post<any>("http://127.0.0.1:3000/api/postData", loc_json).subscribe(response =>{
console.log("Post to nodejs from angular")
console.log(response);
});
nodejs using express: app.js
const express = require('express')
const api_helper = require('./API_helper')
const port = 3000
const cors = require('cors')
const app = express()
app.use(cors())
// allowCrossDomain = function(req, res, next) {
// res.header('Access-Control-Allow-Origin', '*');
// res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
// res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');
// if ('OPTIONS' === req.method) {
// res.send(200);
// } else {
// next();
// }
// };
// app.use(allowCrossDomain);
app.get('/', (req, res, next) => {
res.send("wtffffffffffffffffff");//send to the page
})
app.post('/getAPIResponse', (req, res, next) => {
api_helper.make_API_call('https://jsonplaceholder.typicode.com/posts')
.then(response => {
res.json(response)
})
.catch(error => {
res.send(error)
})
})
//angular --> nodejs
app.post('/api/postData', function(request, response){
//console.log("postData on nodejs 3000");
// const loc_nodejs = req.body;
// console.log("loc_nodejs.loc ", loc_nodejs);
console.log(request.body);
})
app.listen(port, () => console.log(`NodeJS App listening on port ${port}!`))
Because you are using Sec-Fetch-Mode: cors in your request, then your API in Express needs to have CORS enabled and configured correctly. If you are doing local development, I would turn CORS off and enable it in production, but you also may be running two processes for the Angular app and the Express app. In that case, follow the documentation for Express to enable CORS on the API via the documentation below.
https://expressjs.com/en/resources/middleware/cors.html
I added these in my code and they appeared deprecated in the pic, but it does work
const bp = require('body-parser');
app.use(bp.json())
app.use(bp.urlencoded({ extended: true }))\

Cannot send Authorization header to Node 11 / Express 4 server using Angular 7

I cannot send the Authorization header via a GET request from my angular front to my node back, that are on the same VPS.
To make the request from angular I use
return this.httpClient.get<ApiResponse>(ApiClientService.apiAddress + ApiClientService.secureRoute + '/posts');
And use this http interceptor from JwtModule that sets the authorization header, in app.module.ts
imports: [
...,
JwtModule.forRoot({
config: {
tokenGetter,
whitelistedDomains: [ApiClientService.apiAddress, 'vps.ip.address:VPS_FRONT_PORT', 'localhost:BACK_PORT', 'localhost:FRONT_PORT'], //todo clean
}
}),
When I look the request in chromium inspector on the front I see
GET /secure/posts HTTP/1.1
Host: vps.ip.address:VPS_BACK_PORT
Connection: keep-alive
Accept: application/json, text/plain, */*
Origin: vps.ip.address:VPS_FRONT_PORT
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/73.0.3683.86 Chrome/73.0.3683.86 Safari/537.36
Referer: vps.ip.address:VPS_FRONT_PORT/posts
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,fr;q=0.8
We notice that the Authorization header is missing.
The problem does not come from the interceptor IMO, as
When making the same request, but to google.com, I see the Authorization header in the chrome inspector
When adding the headers manually, without an interceptor, I have the same problem
Which makes me think that the problem comes from the CORS/preflight request configuration of my node server. api.config.js
app.use(function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*, localhost, localhost:FRONT_PORT, vps.ip.address:VPS_FRONT_PORT'); //todo change *
res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
res.header('Access-Control-Allow-Credentials', true);
next();
})
...
const secureApi = express.Router();
app.use('/secure', secureApi);
secureApi.use(checkToken);
ProblemRoute.init(secureApi);
PostRoute.init(secureApi);
app.use(function (err, req, res, next) {
console.error(err.stack);
res.status(500).send('Something broke!');
});
const ApiConfig = {
app: app
};
module.exports = ApiConfig;
I read the Authorization header on the node server. secureRoute.js
const jwt = require('jsonwebtoken');
module.exports = function checkToken(req, res, next) {
const authHeader = req.headers['authorization'];
console.log(req.headers);
if (authHeader.startsWith("Bearer ")) {
const token = authHeader.substring(7, authHeader.length);
if (token) {
jwt.verify(token, 'my_secret_key', (err, decode) => {
if (err) {
res.status(400).json({
"message": "Invalid token",
});
} else {
next();
}
})
} else {
res.status(400).json({
"message": "Token must be provided in header for endpoint access",
});
}
} else {
res.status(400).json({
"message": "Token must be provided in header for endpoint access",
});
}
};
Which of course causes an error because the Authorization header is missing from the angular front request.
TypeError: Cannot read property 'startsWith' of undefined
at checkToken (/home/me/project/node-project/config/secureRoute.js:6:20)
When I make a similar request with postman it works correctly, this is the postman developer console log
GET
/snap/postman/81/usr/share/Postman/resources/app/html/vps.ip.address:BACK_PORT/secure/posts
Content-Type: application/json cache-control: no-cache Postman-Token:
10a5caf7-711e-4c39-9437-58dd825ca05f Authorization: Bearer
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJtYWlsIjoicGF1bEBiZWxsb2Mub3ZoIiwiaWF0IjoxNTU1ODgzMjgxLCJleHAiOjE1NTU5Njk2ODF9.s6z5hBLJWEdlDgzw9E9ePiLWj9hqmd39RF68FNRlgLk
User-Agent: PostmanRuntime/7.6.0 Accept: / Host: vps.ip.address:BACK_PORT
accept-encoding: gzip, deflate
And the node server reads the request / headers and answers 200 and content, as expected.
Finally the error, I think, comes from the interceptor I misconfigured. I included the 'http://' part in the whitelisted domain, which makes it act incorrectly I believe.
I also started using the cors npm package, but I don't think this was the fix.

XHR pre-flight with Express Node.js

I'm trying to make a "MEVN" application (MongoDB, Express, Vue, NodeJs).
On the client side, I have a vue component which provides a form to create a post. The post is basically a title and a description. So I have something like this :
methods: {
async addPost () {
await PostsService.addPost({
title: this.title,
description: this.description
})
this.$router.push({ name: 'Posts' })
}
}
My PostsService is a helper to handle posts :
import Api from '#/services/Api'
export default {
addPost (params) {
return Api().post('posts', params)
},
}
My Api is a simple axios constructor :
import axios from 'axios'
export default() => {
return axios.create({
baseURL: `http://localhost:8081`
})
}
On the server side, I have an entry point :
var express = require('express')
, app = express()
app.use(require('./controllers'))
app.listen(8081, function() {
console.log('Listening on port 8081...')
})
Which initiate a controller loader :
var express = require('express')
, router = express.Router()
router.use('/posts', require('./posts'))
module.exports = router
The post controller looks like this :
var express = require('express')
, router = express.Router()
, Post = require('../models/post')
// Add new post
router.post('/posts', function(req, res) {
var title = req.title;
var description = req.description;
post = Post.create(title, description);
if(post) {
res.send({flag: 'SUCCESS', content: post})
} else {
res.send({flag: 'ERROR', content: 'Failed to create the post'})
}
})
module.exports = router
As you can see there is some action with models/post which will make a db connection and save the post.
When I start my server using npm start, I have the confirmation I'm listenning on port 8081.
When I call the addPost() function, I get two XHR requests :
First XHR
Request URL: http://localhost:8081/posts
Request Method: OPTIONS
Status Code: 204 No Content
Remote Address: [::1]:8081
Referrer Policy: no-referrer-when-downgrade
Access-Control-Allow-Headers: content-type
Access-Control-Allow-Methods: GET,HEAD,PUT,PATCH,POST,DELETE
Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 0
Date: Sun, 15 Jul 2018 18:20:01 GMT
Vary: Access-Control-Request-Headers
X-Powered-By: Express
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en,fr-FR;q=0.9,fr;q=0.8,en-US;q=0.7,en-GB;q=0.6
Access-Control-Request-Headers: content-type
Access-Control-Request-Method: POST
Connection: keep-alive
Host: localhost:8081
Origin: http://localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36
Second XHR
Request URL: http://localhost:8081/posts
Request Method: POST
Status Code: 404 Not Found
Remote Address: [::1]:8081
Referrer Policy: no-referrer-when-downgrade
Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 145
Content-Security-Policy: default-src 'self'
Content-Type: text/html; charset=utf-8
Date: Sun, 15 Jul 2018 18:20:01 GMT
X-Content-Type-Options: nosniff
X-Powered-By: Express
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en,fr-FR;q=0.9,fr;q=0.8,en-US;q=0.7,en-GB;q=0.6
Connection: keep-alive
Content-Length: 35
Content-Type: application/json;charset=UTF-8
Host: localhost:8081
Origin: http://localhost:8080
Referer: http://localhost:8080/posts/new
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36
{title: "test", description: "test"}
The second XHR fails and tells me : Cannot POST /posts
Can you explain me what happens and how to fix it ?
Thanks
Your route handler is for /posts/posts so you don't actually have a route handler for just /posts. The first part of the /posts/posts path comes from here:
router.use('/posts', require('./posts'))
The second /posts that adds onto the first comes from:
router.post('/posts', function(req, res) {...}
These two are additive so the URL you have a handler for is /posts/posts.
I'm guessing that the OPTIONS request works because you have some generic CORS middleware installed that is approving all routes when requested with OPTIONS. The second request fails because there is no route handler for just /posts, only one for /posts/posts.
You can fix this by either changing this:
router.use('/posts', require('./posts'))
to:
router.use(require('./posts'))
Or, by changing this:
router.post('/posts', function(req, res) {..}
to this:
router.post('/', function(req, res) {..}
Which ones to choose depends upon whether you want every route on your post controller router to inherit /posts as the root of the path or whether you want to define multiple routes at the top level in your post controller router.

Nodejs API : CORS seems to be enabled by default

Here is my problem: I have a site exemple.com and a node server where is my API running on exemple.com:3000. I want my API to be accessible only by exemple.com.
So I thought that Same-Origin Policy would have block every request from every site except mine if I send in the response the header : Access-Control-Allow-Origin: https:exemple.com.
The problem is that if I call the url : http://exemple.com:3000/api/v1/test/search on another site, I have the error:
Failed to load https://exemple:3000/api/v1/test/search: The 'Access-Control-Allow-Origin' header has a value 'https://exemple.com' that is not equal to the supplied origin. Origin 'http://randomsite.com' is therefore not allowed access.
But in the network tab, I have the response with a 200 status and all the results.
How is it possible to have the error and the result at the same time ? Here is my code :
app.js
const corsApiOptions = {
origin: 'https://exemple.com',
originSuccessStatus: 200,
};
app.use('/api/v1', cors(corsApiOptions), api);
routes/api.js
const express = require('express'); const mongoose =
require('mongoose'); const mongoosastic = require('mongoosastic');
const AssoSchema = require('../schemas/assoSchema');
const router = express.Router();
router.post('/assos/search', (req, res) => { let { query } =
req.body; if (query && query.length > 0) {
query = query
.split(' ')
.map(el => `${el}~`)
.join(' ');
mongoose.connect('mongodb://localhost/mydb');
AssoSchema.plugin(mongoosastic);
const Asso = mongoose.model('asso', AssoSchema, 'assos');
Asso.search(
{
query_string: { query },
},
{ hydrate: true },
(err, results) => {
if (err) res.json({ error: err });
res.json(results.hits.hits);
},
); } else res.json(''); });
module.exports = router;
Here are the results if I make an ajax request from the console of randomsite.com
//General
Request URL: https://exemple.com:3000/api/v1/test/search
Request Method: POST
Status Code: 200 OK
Remote Address: X.X.X.X:3000
Referrer Policy: no-referrer-when-downgrade
//Response Headers
Access-Control-Allow-Origin: https://exemple.com
Connection: keep-alive
Content-Length: 10022
Content-Type: application/json; charset=utf-8
Date: Fri, 30 Mar 2018 10:52:25 GMT
ETag: W/"2726-3/3tY5WvDTtyKm4KPBifg2dP7mI"
Vary: Origin
X-Powered-By: Express
//Request Headers
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7
Connection: keep-alive
Content-Length: 21
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Host: exemple.com:3000
Origin: http://randomsite.com
Referer: http://random.site.com/
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36
//Form Data
query: random search
And in the preview tab I can see all my 10 results in json.
I want my api to accessed only from exemple.com, can someone help me on that ?
But in the network tab, I have the response with a 200 status and all the results.
How is it possible to have the error and the result at the same time ?
The Same Origin Policy prevents JavaScript (embedded in a web page on a different origin) from reading the data in the response.
It is enforced by the browser.
It doesn't prevent the request being made.
It doesn't prevent the browser from getting the response.
It doesn't prevent the owner of the browser from seeing the response through other means (such as the Network tab) and even if it did, they could just make the HTTP request using another tool, such as cURL.
CORS allows a server to tell the browser to relax the Same Origin Policy and allow the JavaScript access to the data.
I want my api to accessed only from exemple.com, can someone help me on that ?
This isn't possible.
JavaScript on other origins won't be able to read the data directly, but it does nothing for non-JS approaches or indirect (e.g. via a proxy) approaches.

302 redirect after CORS preflight request to nodejs server

I try to build a platform, which consists of 2 separated parts, the backend and the frontend.
The backend is powered by Express.js and Passport.js. It's available via localhost:3000.
The frontend uses Googles polymer-1.0 and is running on localhost:8001.
I want to do all API stuff on my backend. The Ui calls and get data from the backend.
When try to do an iron-ajax request for authorization to my backend route, I'm getting a CORS error:
XMLHttpRequest cannot load http://localhost:3000/auth/facebook.
The request was redirected to 'https://www.facebook.com/v2.2/dialog/oauth?response_type=code&redirect_uri=…%3A3000%2Fauth%2Ffacebook%2Fcallback&scope=email&client_id=0815',
which is disallowed for cross-origin requests that require preflight.
UI snippet:
iron-ajax
id="login"
url=""
method="GET"
headers='{"X-Requested-With": "XMLHttpRequest"}'
handle-as="json"
on-response="hresponse"
debounce-duration="300">
/iron-ajax>
_handleTap: function () {
var url = 'http://localhost:3000/auth/' + this.service;
this.$.login.url = url;
this.$.login.generateRequest();
},
Backend snippet:
app.get('/auth/facebook', passport.authenticate('facebook', { scope: 'email' }));
app.get('/auth/facebook/callback', passport.authenticate('facebook'), function(req, res) {
res.status(200).json({
success: true,
message: 'Enjoy!',
redirect: '/route/to/nowhere',
}).end();
});
As you can see, I'm just using the simple Facebook auth snippet from passport.js documenation.
There were 2 request proceeded:
PREFLIGHT:
RESPONSE
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept
Allow: GET,HEAD
Content-Type: text/html; charset=utf-8
Content-Length: 8
ETag: W/"8-8ww6QOmj5lyGjHVKXelZGQ"
Date: Tue, 26 Jan 2016 12:59:20 GMT
Connection: keep-alive
REQUEST
OPTIONS /auth/facebook HTTP/1.1
Host: localhost:3000
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: http://localhost:8001
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36
Access-Control-Request-Headers: accept, x-requested-with
Accept: */*
DNT: 1
Referer: http://localhost:8001/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
GET:
RESPONSE
HTTP/1.1 302 Found
X-Powered-By: Express
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept
Location: https://www.facebook.com/v2.2/dialog/oauth?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauth%2Ffacebook%2Fcallback&scope=email&client_id=0815
Content-Length: 0
Date: Tue, 26 Jan 2016 12:59:20 GMT
Connection: keep-alive
REQUEST
GET /auth/facebook HTTP/1.1
Host: localhost:3000
Connection: keep-alive
accept: application/json
Origin: http://localhost:8001
x-requested-with: XMLHttpRequest
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36
DNT: 1
Referer: http://localhost:8001/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
My node.js server also accepts CORS requests
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
next();
});
When using localhost:3000/auth/facebook as a link, I get my json response from the backend and on port 3000, but that is not what I want.
Is there a possibility to handle such API requests via an own API interface, like mine? Currently I see here a big show stopper.
Thanks & BR;
andre
I think the issue has to do with redirection and CORS.
Redirections with the status codes of 301, 302, 303, 307, or 308, will get you an error.
This is being changed, but for now you need a workaround such as sending back the redirect URL in the response header or body, without using a redirect.
This is well explained in this reply
The only way for a user to authenticate with Facebook is if you actually send the user to Facebook. Doing an XMLHttpRequest won't work because there is no way for the user to login to their Facebook account, approve your application, etc. You must actually redirect the user's browser.
Change your _handleTap function to this:
_handleTap: function () {
var url = 'http://localhost:3000/auth/' + this.service;
window.location = url
}
You need to add this middleware to all your request this way
app.all('/*', function(req, res, next) {
res.header('Access-Control-Allow-Origin', req.headers.origin || '*');
res.header('Access-Control-Allow-Methods', 'GET,POST,PUT,HEAD,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'content-Type,x-requested-with');
next();
});
like explained here How to allow CORS in Express/Node.js?
This error basically means, the server is not accepting Cross Origin Requests (Requests from other domains). In express.js you can use a middleware to enable your server to do this.
var cors = require('cors');
app.use(cors());

Resources