How I can create user with REST_API wordpress? - angularjs

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.

Related

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

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)

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.

when user want to login : AXIOS ERROR: [Error: Request failed with status code 401] BAD_REQUEST

i have a react native app and want to login EXISTING USER IN DATABASE with username and password for get the accesstoken and refreshtoken from api/login. but i get 401 error .
error in docker log:
app_1 | 2022-06-23 20:56:55.997 ERROR 1 --- [nio-8080-exec-3] c.r.hamsafar
.service.UsersServiceImpl : User Not Found In Database
app_1 | Hibernate:
app_1 | select
app_1 | users0_.id as id1_1_,
app_1 | users0_.activation_code as activati2_1_,
app_1 | users0_.active as active3_1_,
app_1 | users0_.disabled as disabled4_1_,
app_1 | users0_.failed_try_count as failed_t5_1_,
app_1 | users0_.family as family6_1_,
app_1 | users0_.lock_time as lock_tim7_1_,
app_1 | users0_.name as name8_1_,
app_1 | users0_.national_code as national9_1_,
app_1 | users0_.password as passwor10_1_,
app_1 | users0_.sms_time as sms_tim11_1_,
app_1 | users0_.username as usernam12_1_
app_1 | from
app_1 | users users0_
app_1 | where
app_1 | users0_.username=?
This is while the user is in the database and it works with the same username and password correctly and without error in postman.
axios codes:
var formData = new FormData();
formData.append('username', '0123456789');
formData.append('password', '0123456789');
axios.post(
'http://1.2.3.4:5555/api/login'
, { formData })
.then(response => {
console.log("RESPONSE RECEIVED: ", response);
})
.catch((err) => {
console.log("AXIOS ERROR: ", err);
})
please help me
Often these types of error is because your server expects a content-type header, in order to understand how to parse the request body (your form in this case).
Look closely at the request from Postman that works, what does it have that you're omitting in your code?
If you've added form data, I believe postman automatically adds the Content-Type header for the appropriate data you've added.
Try editing your code to something like this (removed wrapping formData in an object & added multipart/form-data content-type header):
var formData = new FormData();
formData.append('username', '0123456789');
formData.append('password', '0123456789');
axios.post('http://1.2.3.4:5555/api/login', formData, {
headers: {
'Content-Type': 'multipart/form-data',
}
})
.then((response) => {
console.log('RESPONSE RECEIVED: ', response);
})
.catch((err) => {
console.log('AXIOS ERROR: ', err);
});
Update based on comment revealing Postman using Content-Type application/json:
Try changing header & body to json instead, if that's what your server expects & works in postman:
const data = { username: '0123456789', password: '0123456789' };
axios.post('http://1.2.3.4:5555/api/login', data, {
headers: {
'Content-Type': 'application/json',
}
})
.then((response) => {
console.log('RESPONSE RECEIVED: ', response);
})
.catch((err) => {
console.log('AXIOS ERROR: ', err);
});
https://stackoverflow.com/users/6730803/fredrik-sch%c3%b6n
https://stackoverflow.com/users/10237430/abir-taheer
i solved my problem with used the username and password in url like this:
'http://1.2.3.4:5555/api/login?username='0123456789'&password='0123456789''
thank you from :
https://stackoverflow.com/users/6730803/fredrik-sch%c3%b6n
&
https://stackoverflow.com/users/10237430/abir-taheer
&
https://stackoverflow.com

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}
/>

Null values in address, county, state and city keys

LOG:
2018-03-06T16:45:22.452Z c24b7465-215d-11e8-aefd-bfbf7ac6d9a8
{
addressLine1: null,
addressLine2: null,
addressLine3: null,
districtOrCounty: null,
stateOrRegion: null,
city: null,
countryCode: 'US',
postalCode: '63101'
}
Permission was granted through the companion app,
I got a valid consent Token, apiEndpoint and deviceId
Token: eyJ0eXAiOiJKV1QiLCJhXXX
Api Endpoint: https://api.amazonalexa.com
Device ID: amzn1.ask.device.AETPMACRXXX
My Code:
const token = event.context.System.apiAccessToken
const apiEndpoint = event.context.System.apiEndpoint
const deviceId = event.context.System.device.deviceId
console.log(
`Token: ${token} \n
Api Endpoint: ${apiEndpoint}
Device ID: ${deviceId}`)
const deviceAddressService = new Alexa.services.DeviceAddressService()
const fullAddress = deviceAddressService.getFullAddress(deviceId,apiEndpoint,token).then(data => {
resolve(data)
})
.catch(err => {
reject(err.message)
})
})
Permission in Developer Portal enabled
I only get the postal and country code... any ideas?
The reason why I got only the postal code and country had nothing to do with the code or any settings in the developer portal but with the echo dot itself. In my alexa app under my echo dot the address given only contained the postal code and country

Resources