Cross-Origin Request Blocked and Preflight executes View Django-project - reactjs

In my Django and React project, I am trying to make a registration request which is failing due to a missing "Access-Control-Allow-Origin" header, resulting in a 504 error. The problem I believe I am facing is that the preflight (OPTIONS) request is already executing the View, which is causing issues with permissions for the subsequent POST request.
Jan 21 10:11:20 AllKids python3[155868]: [21/Jan/2023 09:11:20] "OPTIONS /user/register/ HTTP/1.0" 200 0
Jan 21 10:11:20 AllKids python3[155868]: in View
I am not sure why this issue is only occurring on this View, as all other views are working correctly.
Jan 21 10:21:40 AllKids python3[156001]: [21/Jan/2023 09:21:40] "POST /user/validatePassword/ HTTP/1.0" 200 613
It is worth noting that the OPTIONS request is returning a 200 status code. I would like to share the following code with you for further analysis:
let formData = {
password: password,
username: username,
email: email,
};
console.log(formData);
let request = await fetch(
`${process.env.REACT_APP_BACKEND_URL}/user/register/`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formData),
}
);
console.log(response, 'WTF');
let response = await request.json();
The "WTF" line is not being reached since I am not getting the response... For comparison, here is an function that works perfectly fine(login):
let formData = { password: password, email: email };
let request = await fetch(
`${process.env.REACT_APP_BACKEND_URL}/user/validatePassword/`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formData),
}
);
let response = await request.json();
here are my Django settings:
INSTALLED_APPS = [
...
"corsheaders",
]
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',
]
CORS_ORIGIN_ALLOW_ALL = True
here is the View which is being executed on the preflight request:
#api_view(["POST"])
def registerUser(request):
print("In Function")
body = returnContent(request)
try:
CustomUser.objects.get(email=body["email"])
return Response("Email already in use!")
except:
if len(body["username"]) < 4:
return Response("Username should be at least 3 characters long.")
if body["username"][0].isdigit():
return Response("Username should not start with a digit.")
if len(body["password"]) < 7:
return Response("Password must be at least 6 characters")
randomToken = random.randrange(100000, 999999)
user = CustomUser.objects.create_user(
username=body["username"], email=body["email"], password=body["password"], currentVerificationToken=randomToken)
sendEmailVerification(
user.username, user.currentVerificationToken, user.email)
user = CustomUserLoggedSerializer(user, many=False)
return Response(user.data)
and this would be the login request where everything works just fine...:
#api_view(["POST"])
def validatePassword(request):
body = returnContent(request)
try:
password = body["password"]
email = body["email"]
except:
return Response("No Email or Password provided")
try:
user = CustomUser.objects.get(email=email)
except:
return Response("Invalid email")
user = authenticate(request, email=email, password=password)
if user is not None:
if user.twoFactorVerification:
setattr(user, "currentVerificationToken",
random.randrange(100000, 999999))
user.save()
sendEmailVerification(
user.username, user.currentVerificationToken, user.email)
return Response("Two-Factor Authentication Required")
login(request, user)
user = CustomUserLoggedSerializer(user, many=False)
return Response(user.data)
else:
return Response(False)

Related

Google Registration, jwt staying logged in

I just added a feature to be able to register with Google. For security reasons I added a field in the db that is false if the user is registered the usal way(Username & PW) and true if he is registered with google.
class CustomUser(AbstractUser):
objects = UserManager()
REQUIRED_FIELDS = []
USERNAME_FIELD = 'email'
username = models.CharField(max_length=40, unique=False,null=True, blank=True)
email = models.EmailField(_('email address'), unique=True)
profile_image = models.ImageField(null=True,blank=True,default = "users.png",upload_to='',)
created = models.DateTimeField(auto_now_add=True)
id = models.UUIDField(default=uuid.uuid4, unique=True,primary_key=True, editable=False)
telephone = models.CharField(blank=True, max_length=20, null=True)
email_is_verified = models.BooleanField(default = False, null=False, blank = False)
currentVerificationToken = models.CharField(max_length = 6, default="000000")
withGoogleRegistered = models.BooleanField(default = False)
def __str__(self):
return self.email
So if you try to login the usal way but the email adress is bounded to an google registered account, you wont be able to. If you try to login with a usal way bounded email adress, but its connected to a google bounded account , you wont be able to. So, I made this in order to seperate betweena accounts with a password and accounts without a password... But there is a little problem now. In Order to obtain an refresh token (JWT) I have to give a username and a password, otherwise I wont be able to get one in the first place...
function fetchToken() {
if (user && !Object.hasOwn(user, "fromBackend")) {
fetch("http://127.0.0.1:8000/token/", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
email: user.email,
password: user.password,
}),
})
.then((response) => response.json())
.then((data) => {
if (data.access) {
setRemoveTokens(data);
updateUser();
}
});
} else if (localStorage.getItem("refreshToken-allkids") != null) {
getNewTokens();
updateUser();
}
For this I am using rest_framework_simplejw
from django.contrib import admin
from django.urls import path, include
from rest_framework_simplejwt.views import (
TokenObtainPairView,
TokenRefreshView,
)
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path("user/", include("User.urls")),
path("token/", TokenObtainPairView.as_view(), name="obtain_token"),
path("token/refresh/", TokenRefreshView.as_view(), name="refresh_token"),
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
So that beeing said, lets move on to the question: how can I obtain a refresh token for Google registered Accounts without having a Password?
Here is the way I create a google registered account:
#api_view(["POST"])
def googleRegistrationOrLogin(request):
body = request.body.decode('utf-8')
token = json.loads(body)
CLIENT_ID = "591603096190-1fv6asqdpmm6td8t66as5temri420j8b.apps.googleusercontent.com"
try:
idinfo = id_token.verify_oauth2_token(token, requests.Request(), CLIENT_ID)
except:
print("Failure")
return Response("Failure")
try:
user = CustomUser.objects.get(email = idinfo["email"])
if user.withGoogleRegistered:
login(request, user)
user = CustomUserLoggedSerializer(user, many = False)
return Response(user.data)
else:
return Response("Email already in use, please create an account the usal way.")
except:
randomEmailToken = random.randrange(100000,999999)
try:
user = CustomUser.objects.create(username = idinfo["name"],profile_image = idinfo["picture"],withGoogleRegistered = True,password="GoogleRegistered", email = idinfo["email"],currentVerificationToken=randomEmailToken, email_is_verified = True if idinfo["email_verified"] else False)
except:
return Response("Fatal Error")
user = CustomUserLoggedSerializer(user, many = False)
return Response(user.data)
I know its currently not clean, but fair enough for now.

getting google oauth to work with flask, react, postgresql. keep getting internal server error and cors errors

I'm trying to get google oauth to work with flask and react. When I run the server and try to log in, the google sign-in window pops up and immediately closes down and I get an internal server error. in my flask terminal I get this error:
raise MissingCodeError("Missing code parameter in response.")
oauthlib.oauth2.rfc6749.errors.MissingCodeError: (missing_code) Missing code parameter in response.
Any thoughts?
app.py
#app.route('/login', methods=['POST'])
#cross_origin()
def login():
google_provider = get_google_provider()
auth_endpoint = google_provider["authorization_endpoint"]
request_uri = client.prepare_request_uri(
authorization_endpoint,
redirect_uri=request.base_url + "/callback",
scope=["openid", "email", "profile"]
)
return redirect(request_uri)
#app.route('/login/callback', methods=['GET', 'POST'])
#cross_origin()
def login_callback():
code = request.json.get("access token")
print("**************")
# print(list(request.args.keys()))
print(request.json)
print("**************")
token, headers, body = client.prepare_token_request(
token_endpoint,
code=code,
authorization_response=request.url,
redirect_url=request.base_url
)
token_response = requests.post(
token_url,
headers=headers,
data=body,
auth=(GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET)
)
client.parse_request_body_response(json.dumps(token_response.json()))
userinfo_endpoint = google_provider["userinfo_endpoint"]
uri, headers, body = client.add_token(userinfo_endpoint)
userinfo_response = request.get(uri, headers=headers, data=body)
if userinfo_response.json().get("email_verified"):
unique_id = userinfo_response.json()["sub"]
user_email = userinfo_response.json()["email"]
user_picture = userinfo_response.json()["picture"]
user_name = userinfo_response.json()["given_name"]
user_member_since = datetime.today().strftime('%Y-%m-%d')
else:
print("User email not available or not verified by Google")
user = User(id=unique_id, name=user_name, email=user_email, picture=user_picture, member_since=user_member_since)
if not User.get(unique_id):
User.create(unique_id, user_name, user_email, user_picture, user_member_since)
login_user(user)
redirect(url_for("/new-user-form"))
app.js
googleResponse = (response) => {
const tokenBlob = new Blob([JSON.stringify({access_token: response.accessToken}, null, 2)], {type: 'application/json'});
const options = {
method: 'POST',
body: tokenBlob,
mode: 'cors',
cache: 'default'
}
fetch(`${BASE_URL}/login/callback`, options).then(r => {
if (r.headers.get('Content-Type') === 'text/html; charset=utf-8') {
console.log('error')
return
}
const token = r.headers.get('x-auth-token')
r.json().then(user => {
if (token) {
this.setState({isAuthenticated: true, user, token, message: `${user.name}`})
console.log(token)
}
});
})
}
onFailure = (error) => {
alert(error.data)
}
<Route path='/login'>
<GoogleLogin
clientId={config.GOOGLE_CLIENT_ID}
buttonText="Login"
onSuccess={this.googleResponse}
onFailure={this.onFailure}
/>

Axios post request is being denied by flask made api. CORS error coming up [duplicate]

This question already has an answer here:
cors enable in Request header field Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headers in preflight response
(1 answer)
Closed 2 years ago.
I am trying to add user from my react application through an API made with flask. But the post request is getting in error with the following error.
'http://localhost:5000/api/v1.0/add' from origin 'http://localhost:3000' has been blocked by CORS policy: Request header field access-control-allow-origin is not allowed by Access-Control-Allow-Headers in preflight response.
my axios code is following
const params = {
user_name : '5678234121',
passwd : 'password',
location : 'Kolkata',
pin_code : '700019',
secret_ques: 'What is your mother s maiden name?',
answr : 'aba',
status : 'Active',
remarks : 'test data'
};
const res = await Axios.post(
'http://localhost:5000/api/v1.0/add', params, {
headers: {
'content-type': 'application/json',
'Access-Control-Allow-Origin' : '*',
'Access-Control-Allow-Methods' : 'GET,PUT,POST,DELETE,PATCH,OPTIONS',
},
});
console.log(res.data);
my flask code is following
#app.route('/api/v1.0/add', methods=["POST"])
def add():
con = None
db = datadir + datafile
try:
_json = request.json
_name = _json['user_name']
_psswd = _json['passwd']
_locatn = _json['location']
_pincd = _json['pin_code']
_secrt = _json['secret_ques']
_ans = _json['answr']
_stat = _json['status']
_remks = _json['remarks']
# validate the received values
if _name and _psswd and _pincd and request.method == 'POST':
#do not save password as a plain text
_hashed_password = base64.b64encode(_psswd.encode("utf-8"))
# save edits
sql = '''INSERT INTO user_mast(user_name, passwd, location, pin_code, secret_ques, answr, status, remarks ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)'''
data = (_name, _hashed_password.decode('ASCII'), _locatn, _pincd, _secrt,_ans, _stat, _remks , )
con = sqlite3.connect( db ) # Connection to database
cur = con.cursor()
cur.execute(sql, data)
con.commit()
resp = jsonify({'Status' : 'User added successfully!'})
resp.status_code = 200
else :
resp = jsonify ({'Status' :'Mandatory fields: Name,Password,Pincode missing..'})
resp.status_code = 502
except sqlite3.Error as e:
resp = jsonify({'Status' :'Database Error'})
resp.status_code = 500
except Exception as e:
print(e)
resp = jsonify({'Status' :'Unknown Error : Contact Administrator'})
resp.status_code = 501
finally:
cur.close()
con.close()
return resp
Please help me to fix the error, going clueless about this.
If you're new to this, I'd recommend just adding Flask-CORS to your application and not futzing around with the headers.

Django request.user is becoming empty after login using angularjs

I have Django and angularjs app running separately. I am able to login to system by using angularjs. however after login request.user in django gives empty data.
MIDDLEWARE_CLASSES = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
Login code:
#csrf_exempt
def login_for_new_design(request, *args, **kwargs):
if request.method == "POST":
temp=json.loads(request.body)
username = temp.get("username", None)
password = temp.get("password", None)
user = authenticate(username=username, password=password)
response_data = {}
if user:
login(request, user)
response_data['success'] = True
response_data['message'] = 'Login was succesfull!'
else: # invalid case
response_data['success'] = True
response_data['message'] = 'Login was Failure!'
response = HttpResponse(json.dumps(response_data));
response["Access-Control-Allow-Origin"] = "*"
response["Access-Control-Allow-Methods"] = "POST, GET, OPTIONS"
response["Access-Control-Max-Age"] = "1000"
response["Access-Control-Allow-Headers"] = "*"
return response
ajax method:
$http({
method:'POST',
url:uri,
datatype:"json",
data:payload,
headers: {
'Content-Type': undefined
},
}).then(function(result){
console.log(result)
localStorage.setItem("username", $scope.username);
$state.go('app.main', {showLeftnav: true});
},function(error){
console.log(error)
})
Above two methods works fine.
But when I want test for if user is logged in or not using below method,
#csrf_exempt
def isAuthenticated_user(request):
userdic = {};
userdic['username'] = request.user.username
print userdic
response = HttpResponse(json.dumps(userdic));
response["Access-Control-Allow-Origin"] = "*"
response["Access-Control-Allow-Methods"] = "POST, GET, OPTIONS"
response["Access-Control-Max-Age"] = "1000"
response["Access-Control-Allow-Headers"] = "*"
return response
var csrftoken = $cookies.get('csrftoken')
authPromise = $http({
'method': "POST",
'url': "http://localhost:8000/isAuthenticated_user/",
headers:{
"X-CSRFToken": csrftoken,
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
// 'withCredentials':true
},
})
request.user gives empty data.
Kindly let me know where I am doing wrong.
try,
user = self.request.query_params.get('username',None)
print user
let me know if some error occured

How I can create user with REST_API wordpress?

I need create user on Wordpress. I use WP_REST_API - this is default API for WP. You can look at it "YOU_SITE/wp-json/"
I have ionic3 project and have function.
onSubmit(values){
this.http.post(Config.WORDPRESS_URL + 'wp-json/jwt-auth/v1/token',{
username: 'admin',
password: 'pass'
})
.subscribe(
res => {
let token = res.json().token;
let header : Headers = new Headers();
header.append('Authorization','Basic ' + token);
this.http.post(Config.WORDPRESS_REST_API_URL + 'users?token=' + res.json().token,{
username: values.username,
name: values.displayName,
email: values.email,
password: values.password,
},header)
.subscribe(
result => {
console.log(result.json());
},
error => {
console.log(error.json());
}
)
},
err => {
console.log(err);
}
)
}
But I always get error:
code: "rest_cannot_create_user",
message: "Sorry, but you can't create new user"
status: 401
admin:pass - this is admin on site and has a role admin.
Also I added to .htaccess
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1]
Please help me to find a mistake
I found my issue and solution. I delete param TOKEN from URL and
create options header
let header = new Headers({"Authorization": "Bearer "+token});
let options = new RequestOptions({headers: header});
I have next request
this.http.post(Config.REGISTER, {
username: username,
name: displayName,
email: email,
password: password,
nonce: nonce
}, options)
it is work for me.

Resources