has been blocked by CORS policy
Access to fetch at 'http//..........login.php' from origin 'http://localhost:*******' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.
Als lake weet ik niet zo goed wat ik nu moet doen. Na een paar dagen zoeken via google krijg ik zoveel zoekresultaten/vragen/oplossingen dat ik 'door de bomen het bos niet meer zie'. Veel CORS foutmeldingen lijken op elkaar en antwoorden zijn vaak verschillend.
Oplossingen die ik zelf gevonden heb:
- Kan/moet ik CORS policy uitschakelen? volgens mij mag dat niet ivm beveiliging
- Moet ik nog een server in de frontend maken met node.js? Is dit voor mij van toepassing?
- Moet ik een CORS plugin installeren voor google Chrome? (volgens mij los ik het probleem hiermee niet op)
- In de file index.php moet ik het onderstaande zetten met een paar aanpassingen. (ik heb alleen db.php, signup.php en login.php)
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token');
Hopelijk kan iemand mij hiermee verder helpen.
Zie ook: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
Dit kan je ook in .htaccess regelen
De developer-console van je browser kan je prima gebruiken om te kijken welke headers je terugkrijgt gestuurd bij een aanroep.
In DEVTOOLS staat ook deze error: "POST" http://.......login.php net::ERR_FAILED
Betekent dit dat ik POST moet toestaan?
Zou ik dan het onderstaande in login.php moeten zetten?
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token');
Gewijzigd op 16/12/2021 16:42:17 door - Ariën -
Bedoel je hiermee dat dit ook een oplossing is voor een signin/registratie pagina van een app.
Of wil je hiermee aangeven dat de beveiliging van je database dan zo lek als een mandje is.
www.randomdomeinvaniemand.nl ook een aanroep mag doen naar je scripts via een AJAX-request.
Verder heeft CORS niks te maken met je database.
Ga zelf eens na of Verder heeft CORS niks te maken met je database.
Gewijzigd op 16/12/2021 17:07:44 door - Ariën -
"Ga zelf eens na of www.randomdomeinvaniemand.nl ook een aanroep mag doen naar je scripts via een AJAX-request."
Lijkt me niet, maar het zegt me ook niks. Zou je me willen helpen om het werkend te krijgen?
De uitleg over CORS staat al helder beschreven in de link van Mozilla in dit topic. Met Origin kan je bepalen wie een request mag doen.
Gewijzigd op 16/12/2021 18:00:19 door - Ariën -
'http://localhost:******* lijkt me niet goed als ook andere gebruikers zich willen registeren.
header('Access-Control-Allow-Origin: https://MIJN proxy' ipv *);
header('Access-Control-Allow-Methods: POST);
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token');
Dit gaat over de registratie pagina.
Moet ik bij de inlogpagina (login.php) dit erbij zetten?
Access-Control-Allow-Credentials: true
header("Access-Control-Allow-Origin: http://localhost:19006");
header("Access-Control-Allow-Origin: http://localhost:19002");
header("Access-Control-Allow-Origin: http://localhost:21"); poort hostnet
header("Access-Control-Allow-Origin: mijnwebsite.nl/LoginRegister/login.php");
Volgens mij moet ik de poort bij http://localhost:... zetten.
Weet je waar ik die kan vinden? Ik dacht dat het de eerste twee zijn, maar ik krijg steeds dezelfde Cors foutmelding.
Ik heb nu dit:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
<?php
include('db.php');
header("Access-Control-Allow-Origin: http://localhost:19006");
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header("Access-Control-Allow-Headers: Content-Type, Authorization");
header("Content-Type: application/json");
$UserEmail = $decodedData['Email'];
$UserPW = ($decodedData['Password']); //password is hashed
$SQL = "SELECT * FROM newuser WHERE UserEmail = '$UserEmail'";
$exeSQL = mysqli_query($conn, $SQL);
$checkEmail = mysqli_num_rows($exeSQL);
if ($checkEmail != 0) {
$arrayu = mysqli_fetch_array($exeSQL);
if ($arrayu['UserPw'] != $UserPW) {
$Message = "pw WRONG";
} else {
$Message = "Success";
}
} else {
$Message = "No account yet";
}
$response[] = array("Message" => $Message);
echo json_encode($response);[/code]
--------------------------------------------------------------------------------
[code]import React, { Component } from 'react';
import { View, Pressable, Text, TextInput, TouchableOpacity, Button} from 'react-native';
import stylesin from '../../style';
import Feather from 'react-native-vector-icons/Feather';
export default class signin extends Component {
constructor(props) {
super(props);
this.state = {
email : '',
password : '',
check_textInputChange : false,
secureTextEntry : true,
};
}
InsertRecord=()=>{
var Email = this.state.email;
var Password = this.state.password;
if ((Email.length==0) || (Password.length==0)){
alert("Required Field Is Missing!!!");
}else{
var APIURL = **"http://mywebsite.nl/login.php"**;
var headers = {
'Accept' : 'application/json',
'Content-Type' : 'application/json'
};
var Data ={
Email: Email,
Password: Password
};
fetch(APIURL,{
method: 'POST',
headers: headers,
body: JSON.stringify(Data)
})
.then((Response)=>Response.json())
.then((Response)=>{
alert(Response[0].Message)
if (Response[0].Message == "Success") {
console.log("true")
this.props.navigation.navigate("HomeScreen");
}
console.log(Data);
})
.catch((error)=>{
console.error("ERROR FOUND" + error);
})
}
}
updateSecureTextEntry(){
this.setState({
...this.state,
secureTextEntry: !this.state.secureTextEntry
});
}
render() {
return (
<View style={stylesin.viewStyle}>
<View style={stylesin.action}>
<TextInput
placeholder="Enter Email"
placeholderTextColor="#ff0000"
style={stylesin.textInput}
onChangeText={email=>this.setState({email})}
/>
</View>
<View style={stylesin.action}>
<TextInput
placeholder="Enter Password"
placeholderTextColor="#ff0000"
style={stylesin.textInput}
secureTextEntry={this.state.secureTextEntry ? true : false}
onChangeText={password=>this.setState({password})}
/>
<TouchableOpacity
onPress={this.updateSecureTextEntry.bind(this)}>
{this.state.secureTextEntry ?
<Feather
name="eye-off"
color="grey"
size={20}
/>
:
<Feather
name="eye"
color="black"
size={20}
/>
}
</TouchableOpacity>
</View>
{/* Button */}
<View style={stylesin.loginButtonSection}>
<Pressable
style={stylesin.loginButton}
onPress={()=>{
this.InsertRecord()
}}
>
<Text style={stylesin.text}>Sign In</Text>
</Pressable>
</View>
<View style={stylesin.loginButtonSection}>
<Pressable
style={stylesin.loginButton}
onPress={()=>{
// this.InsertRecord()
}}
>
<Text style={stylesin.text}>Create new Account</Text>
</Pressable>
</View>
</View>
);
}
}[/code]
include('db.php');
header("Access-Control-Allow-Origin: http://localhost:19006");
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header("Access-Control-Allow-Headers: Content-Type, Authorization");
header("Content-Type: application/json");
$UserEmail = $decodedData['Email'];
$UserPW = ($decodedData['Password']); //password is hashed
$SQL = "SELECT * FROM newuser WHERE UserEmail = '$UserEmail'";
$exeSQL = mysqli_query($conn, $SQL);
$checkEmail = mysqli_num_rows($exeSQL);
if ($checkEmail != 0) {
$arrayu = mysqli_fetch_array($exeSQL);
if ($arrayu['UserPw'] != $UserPW) {
$Message = "pw WRONG";
} else {
$Message = "Success";
}
} else {
$Message = "No account yet";
}
$response[] = array("Message" => $Message);
echo json_encode($response);[/code]
--------------------------------------------------------------------------------
[code]import React, { Component } from 'react';
import { View, Pressable, Text, TextInput, TouchableOpacity, Button} from 'react-native';
import stylesin from '../../style';
import Feather from 'react-native-vector-icons/Feather';
export default class signin extends Component {
constructor(props) {
super(props);
this.state = {
email : '',
password : '',
check_textInputChange : false,
secureTextEntry : true,
};
}
InsertRecord=()=>{
var Email = this.state.email;
var Password = this.state.password;
if ((Email.length==0) || (Password.length==0)){
alert("Required Field Is Missing!!!");
}else{
var APIURL = **"http://mywebsite.nl/login.php"**;
var headers = {
'Accept' : 'application/json',
'Content-Type' : 'application/json'
};
var Data ={
Email: Email,
Password: Password
};
fetch(APIURL,{
method: 'POST',
headers: headers,
body: JSON.stringify(Data)
})
.then((Response)=>Response.json())
.then((Response)=>{
alert(Response[0].Message)
if (Response[0].Message == "Success") {
console.log("true")
this.props.navigation.navigate("HomeScreen");
}
console.log(Data);
})
.catch((error)=>{
console.error("ERROR FOUND" + error);
})
}
}
updateSecureTextEntry(){
this.setState({
...this.state,
secureTextEntry: !this.state.secureTextEntry
});
}
render() {
return (
<View style={stylesin.viewStyle}>
<View style={stylesin.action}>
<TextInput
placeholder="Enter Email"
placeholderTextColor="#ff0000"
style={stylesin.textInput}
onChangeText={email=>this.setState({email})}
/>
</View>
<View style={stylesin.action}>
<TextInput
placeholder="Enter Password"
placeholderTextColor="#ff0000"
style={stylesin.textInput}
secureTextEntry={this.state.secureTextEntry ? true : false}
onChangeText={password=>this.setState({password})}
/>
<TouchableOpacity
onPress={this.updateSecureTextEntry.bind(this)}>
{this.state.secureTextEntry ?
<Feather
name="eye-off"
color="grey"
size={20}
/>
:
<Feather
name="eye"
color="black"
size={20}
/>
}
</TouchableOpacity>
</View>
{/* Button */}
<View style={stylesin.loginButtonSection}>
<Pressable
style={stylesin.loginButton}
onPress={()=>{
this.InsertRecord()
}}
>
<Text style={stylesin.text}>Sign In</Text>
</Pressable>
</View>
<View style={stylesin.loginButtonSection}>
<Pressable
style={stylesin.loginButton}
onPress={()=>{
// this.InsertRecord()
}}
>
<Text style={stylesin.text}>Create new Account</Text>
</Pressable>
</View>
</View>
);
}
}[/code]
Gewijzigd op 20/12/2021 14:33:38 door werner g
Welke poorten zoek je dan precies? En weet je zeker dat je wel 'localhost' wilt? Of doe je dat vanwege je proxy?
En waarom poort 21 van FTP? Die doet niks met HTTP-requests hoor.
Gewijzigd op 20/12/2021 15:13:55 door - Ariën -
Dat klopt inderdaad, maar dan zou ik moeten kiezen voor:
header("Access-Control-Allow-Origin: *");
Maar dan kan iedereen toegang krijgen tot de database, toch ook buiten de app? Dat is ook niet de bedoeling ivm veiligheid.
Welke poorten zoek je dan precies? En weet je zeker dat je wel 'localhost' wilt? Of doe je dat vanwege je proxy?
Eigenlijk wou ik geen localhost maar dat werd aanbevolen, waarom begrijp ik ook niet echt.
IEn waarom poort 21 van FTP? Die doet niks met HTTP-requests hoor.
Dat had ik hier inderdaad niet moeten zetten, dat was een laatste poging omdat ik er niet meer uitkwam.
Ik heb het idee dat je maar een beetje aanrommelt, zonder te weten wat je doet. Dat lijkt mij erg gevaarlijk, los van CORS.
CORS is meer een drempel dan een echte beveiliging. Je kan er mee bepalen welke externe sites jouw scripts mogen aanroepen. Als iemand het los via bijv. wget of cURL aanroept, dan kan dat gewoon.
Gewijzigd op 21/12/2021 10:06:31 door - Ariën -
De reden dat ik het vraag is dat ik een goed beveiligde en werkende oplossing zoek.
Los van dit onderwerp heeft het weinig te maken met "erg gevaarlijk", het overige is alleen het schrijven van een app.
Gewijzigd op 21/12/2021 11:02:28 door werner g
Dat schept meer duidelijkheid over CORS.
Verder help ik iedereen graag hoor. :-)
Gewijzigd op 21/12/2021 10:12:48 door - Ariën -
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
How to avoid the CORS preflight
The code in the question triggers a CORS preflightsince it sends an Authorization header.
https://developer.mozilla.org/docs/Web/HTTP/Access_control_CORS#Preflighted_requests
Even without that, the Content-Type: application/json header will also trigger a preflight.
What preflight means: before the browser tries the POST in the code in the question, it first sends an OPTIONS request to the server, to determine if the server is opting-in to receiving a cross-origin POST that has Authorization and Content-Type: application/json headers.
It works pretty well with a small curl script - I get my data.
To properly test with curl, you must emulate the preflight OPTIONS the browser sends:
curl -i -X OPTIONS -H "Origin: http://127.0.0.1:3000" \
-H 'Access-Control-Request-Method: POST' \
-H 'Access-Control-Request-Headers: Content-Type, Authorization' \
"https://the.sign_in.url"
with https://the.sign_in.url replaced by whatever your actual sign_in URL is.
The response the browser needs from that OPTIONS request must have headers like this:
Access-Control-Allow-Origin: http://127.0.0.1:3000
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: Content-Type, Authorization
If the OPTIONS response doesnt include those headers, the browser will stop right there and never attempt to send the POST request. Also, the HTTP status code for the response must be a 2xxtypically 200 or 204. If its any other status code, the browser will stop right there.
The server in the question responds to the OPTIONS request with a 501 status code, which apparently means its trying to indicate it doesnt implement support for OPTIONS requests. Other servers typically respond with a 405 Method not allowed status code in this case.
So youll never be able to make POST requests directly to that server from your frontend JavaScript code if the server responds to that OPTIONS request with a 405 or 501 or anything other than a 200 or 204 or if doesnt respond with those necessary response headers.
The way to avoid triggering a preflight for the case in the question would be:
if the server didnt require an Authorization request header but instead, e.g., relied on authentication data embedded in the body of the POST request or as a query param
if the server didnt require the POST body to have a Content-Type: application/json media type but instead accepted the POST body as application/x-www-form-urlencoded with a parameter named json (or whatever) whose value is the JSON data
The code in the question triggers a CORS preflightsince it sends an Authorization header.
https://developer.mozilla.org/docs/Web/HTTP/Access_control_CORS#Preflighted_requests
Even without that, the Content-Type: application/json header will also trigger a preflight.
What preflight means: before the browser tries the POST in the code in the question, it first sends an OPTIONS request to the server, to determine if the server is opting-in to receiving a cross-origin POST that has Authorization and Content-Type: application/json headers.
It works pretty well with a small curl script - I get my data.
To properly test with curl, you must emulate the preflight OPTIONS the browser sends:
curl -i -X OPTIONS -H "Origin: http://127.0.0.1:3000" \
-H 'Access-Control-Request-Method: POST' \
-H 'Access-Control-Request-Headers: Content-Type, Authorization' \
"https://the.sign_in.url"
with https://the.sign_in.url replaced by whatever your actual sign_in URL is.
The response the browser needs from that OPTIONS request must have headers like this:
Access-Control-Allow-Origin: http://127.0.0.1:3000
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: Content-Type, Authorization
If the OPTIONS response doesnt include those headers, the browser will stop right there and never attempt to send the POST request. Also, the HTTP status code for the response must be a 2xxtypically 200 or 204. If its any other status code, the browser will stop right there.
The server in the question responds to the OPTIONS request with a 501 status code, which apparently means its trying to indicate it doesnt implement support for OPTIONS requests. Other servers typically respond with a 405 Method not allowed status code in this case.
So youll never be able to make POST requests directly to that server from your frontend JavaScript code if the server responds to that OPTIONS request with a 405 or 501 or anything other than a 200 or 204 or if doesnt respond with those necessary response headers.
The way to avoid triggering a preflight for the case in the question would be:
if the server didnt require an Authorization request header but instead, e.g., relied on authentication data embedded in the body of the POST request or as a query param
if the server didnt require the POST body to have a Content-Type: application/json media type but instead accepted the POST body as application/x-www-form-urlencoded with a parameter named json (or whatever) whose value is the JSON data
Gewijzigd op 23/12/2021 11:55:15 door werner g
curl "http://gastgarant.nl/LoginRegister/login.php" ^
-X "OPTIONS" ^
-H "Connection: keep-alive" ^
-H "Accept: */*" ^
-H "Access-Control-Request-Method: POST" ^
-H "Access-Control-Request-Headers: content-type" ^
-H "Origin: http://localhost:19006" ^
In mijn login.php heb ik dit staan:
header("Access-Control-Allow-Origin: http://localhost:19006");
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header("Access-Control-Allow-Headers: Content-Type, Authorization");
header("Content-Type: application/json");
Zou ik dan het onderstaande aan moeten passen?
header("Access-Control-Allow-Origin: http://localhost:19006");
header('Access-Control-Allow-Methods:
header("Access-Control-Allow-Headers: Content-Type
En dit
application/x-www-form-urlencoded with a parameter named json (or whatever) verwerken in mijn signin.js script?
Gewijzigd op 23/12/2021 12:12:23 door werner g
Maar met welke reden sta je alleen localhost toe? Zit je achter een proxy?
header('Access-Control-Allow-Origin: *');
jou reactie: Als je jan-en-alleman een request wilt laten doen, dan kan je dat proberen.
mijn reactie: Bedoel je hiermee dat dit ook een oplossing is voor een signin/registratie pagina van een app. Of wil je hiermee aangeven dat de beveiliging van je database dan zo lek als een mandje is.
jou reactie: Ga zelf eens na of www.randomdomeinvaniemand.nl ook een aanroep mag doen naar je scripts via een AJAX-request.
etc.....
Ik ga ervan uit dat * sowieso niet goed is omdat dan iedereen toegang heeft.
Moet ik dan een Loopback-adres + 19006 gebruiken? Maar dat is toch hetzelfde als localhost?
Of gaat het om een site? Die draait op één hostname.
Verder is CORS een drempel, en geen waterdichte beveiliging. Als de beveiliging in je script die extern aangeroepen wordt goed beveiligd is, dan is het toch ook prima? Zelf zou ik het in sommige gevallen ongewenst vinden als een API-request met data door een externe site uitgelezen wordt. Die afweging moet je zelf maken.
Gewijzigd op 23/12/2021 14:33:22 door - Ariën -
Het gaat inderdaad om een app. Zou je de voorgaande berichten ook willen lezen en aan willen geven wat ik precies moet doen. Stap voor stap. Ik ben loop hier nu al ruim 2 weken op vast en ik kom niks verder.