How to use axios to post to my Django Rest server? - django

I am getting a 403 error when trying to post to my Django server from my frontend mobile app. However, it works totally fine when I post with the form on the browser.
I managed to register once using my frontend mobile app, but ever since then, I get this 403 error. I've tried both signing up and logging in.
Here is the error I get in my Django backend terminal:
Bad Request: /rest-auth/registration/
[16/Aug/2021 14:51:37] "POST /rest-auth/registration/ HTTP/1.1" 403 58
Here is my settings.py file:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'rest_framework.authtoken',
'rest_auth',
'django.contrib.sites',
'allauth',
'allauth.account',
'rest_auth.registration',
'users',
]
SITE_ID = 1
....
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication',
),
}
ACCOUNT_EMAIL_VERIFICATION = 'none'
Here is my front end (register.js):
axios
.post("http://127.0.0.1:8002/rest-auth/registration/", {
username: "tester1234#gmail.com",
email: "tester1234#gmail.com",
password1: "tester1234#gmail.com",
password2: "tester1234#gmail.com",
})
What am I doing wrong? I just want users to be able to register, log in, and log out of my app.

The issue was that I had logged in, and then was not providing the key.
To solve this, I created a logout button, then added a mechanism to save the key and use it in the header.

Related

request.user.is_authenticated is always false in Django rest framework

I am using allauth for authentication in drf. I was able to register new users and login with the credentials.
The login api return response something like this:
{
"key" : "<some token>"
}
Now I have 1 more API the code for which is
from django.http import HttpResponse
def lol(request):
if request.user.is_authenticated:
return HttpResponse("Authenticated")
else:
return HttpResponse("Not Authenticated")
But this is always returning not authenticated
my api call look like this
Here is the list of installed apps in my settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'rest_framework.authtoken',
'rest_auth',
'django.contrib.sites',
'allauth',
'allauth.account',
'rest_auth.registration',
'api.user',
'api.activity',
]
It seems you're using functional views? If so did you add #api_view decorator to the view?
If so did you add authentication_classes=[TokenAuthentication] keyword argument? That's imperative to make token Auth work.
Either that or set the following in settings.py:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication'
]
}

Authenticating user problem with django-tenant-schema

I want to have admin module available to tenants (using django-tenant-schema).
My apps section of settings.py:
# Application definition
SHARED_APPS = (
'tenant_schemas', # mandatory, should always be before any django app
'customers', # you must list the app where your tenant model resides in
# 'django.contrib.sites',
# everything below here is optional
)
TENANT_APPS = (
'django.contrib.contenttypes',
# your tenant-specific apps
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
)
INSTALLED_APPS = (
'tenant_schemas', # mandatory, should always be before any django app
'customers',
# 'django.contrib.sites', #using this will cause error - see my stackoverflow question
'django.contrib.auth',
'django.contrib.admin',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
)
I have set up 2 schemas (tenant1 and public). Created superuser and can see that superuser is created within tenant1 schema. However when trying to log in at tenant1.domain.com/admin, getting login screen but after entering credentials keep getting:
ProgrammingError at /admin/login/ relation "auth_user" does not exist
Looks like it is not picking up my tenant1 schema?
What I have to change in configuration?
Make sure tenant middleware is installed.
It's responsible for negotiating which tenant is called and connecting to the right schemas.

Django request.user is anonymous in views without login_required decorator

I am working on a Django (v2.0) app with django-allauth as auth backend. I'll explain my problem in steps:
User logs in -> user redirected to home page (can't access home page without login)
In the home page (after logging in), several calls are made for a particular view in the server.
Ex: https://mywebsite.com/api/getstuff/123
Problem: getstuff returns/prints data that is intended for a user who is NOT logged in.
getstuff is defined in urls.py as:
url(r'^api/getstuff/(?P<hash_code>[a-zA-Z0-9]{3})$', views.getstuff, name='getstuff')
in views.py: (views.getstuff)
#csrf_protect
#ensure_csrf_cookie
def getstuff(request,hash_code):
if request.user.is_authenticated:
#do stuff....
print('user is authenticated!')
return HttpResponse(hash_code+'foo-auth')
else:
#do other stuff..
print('user is NOT authenticated')
return HttpResponse(hash_code+'foo-un_auth')
I only see user is NOT authenticated being printed in my case. Shouldn't the output be user is authenticated since the user is already logged in? the request.user object is an AnonymousUser object. All the requests I make are from https.
few configurations from settings.py:
CSRF_USE_SESSIONS = True
CSRF_COOKIE_SECURE = True #tried removing this, still same result as above
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sites',
'django_extensions',
'django.contrib.sitemaps',
'mysite.core',
'bootstrapform',
'allauth',
'allauth.account',
'allauth.socialaccount',
'allauth.socialaccount.providers.facebook',
'allauth.socialaccount.providers.google',
'allauth.socialaccount.providers.github',
'allauth.socialaccount.providers.twitter',
'embed',
'channels',
'djcelery'
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'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',
]
AUTHENTICATION_BACKENDS = (
"allauth.account.auth_backends.AuthenticationBackend",
)
I tried clearing cache before accessing the website and logging in - still same result.
Am I missing something? What could be the problem?
Your use of if request.user.is_authenticated: is fine. Change the image src tag to use the domain that you logged into.
<img src="/api/getstuff/123">

Error: Request failed with status code 400. missing headers? error in backend?

I'm sending a POST request using axios to my localhost(this case, it's 10.0.0.2:8000) in React Native (android simulator) and I'm getting 400 error from Django RESTful Framework Backend.
This is my action creator
export const doAuthLogin = ({ username, password }) => dispatch => {
axios.post(`${ROOT_URL}/rest-auth/login/`, {
username,
password
}).then(response => {
console.log(response);
// Save Token post is Already await.
AsyncStorage.setItem('auth_token', response.token);
dispatch({ type: AUTH_LOGIN_SUCCESS, payload: response.token });
})
.catch(response => {
console.log(response);
dispatch({ type: AUTH_LOGIN_FAIL, payload: response.non_field_errors });
});
};
This is error message from Remote Debugger JS. It's just a console.log(response) from catch from axios.post.
Error: Request failed with status code 400
at createError (createError.js:16)
at settle (settle.js:18)
at XMLHttpRequest.handleLoad (xhr.js:77)
at XMLHttpRequest.dispatchEvent (event-target.js:172)
at XMLHttpRequest.setReadyState (XMLHttpRequest.js:538)
at XMLHttpRequest.__didCompleteResponse (XMLHttpRequest.js:381)
at XMLHttpRequest.js:485
at RCTDeviceEventEmitter.emit (EventEmitter.js:181)
at MessageQueue.__callFunction (MessageQueue.js:260)
at MessageQueue.js:101
Error message in console,
[17/Aug/2017 14:14:10] "POST /rest-auth/login/ HTTP/1.1" 400 40
And this is a part of settings.py,
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
INSTALLED_APPS = [
'corsheaders',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'allauth',
'allauth.account',
'rest_auth.registration',
'rest_framework',
'rest_framework.authtoken',
'rest_auth',
'profiles',
'allauth.socialaccount',
'allauth.socialaccount.providers.facebook',
'allauth.socialaccount.providers.twitter',
'django.contrib.sites',
]
SITE_ID = 1
CORS_ORIGIN_WHITELIST = (
'10.0.2.2',
'localhost'
)
I'm thinking I might have an error in action creator. Missing headers or...
This error doesn't give me any hint more than 400 so I'm totally lost. Can you help me with this problem, please?
Thanks
Thanks for commenting guys.
The problem was that I was actually sending undefined to username and password.
{username, password } -> (username, password)
This question was very silly question, this code is perfect. No CORS error, correct response body, and correct allowed hosts. Actually your comments convinced me that I may have a problem in React code. I consoled log variable in each line.
Thank you so much! Now I can sleep

Django rest-auth registration. How to return user_id with the key when using token authentication

I am using Djando rest_auth.registration.
My corresponding entry in urls.py is
url(r'^rest-auth/registration/', include('rest_auth.registration.urls'))
My authentication class is rest_framework.authentication.TokenAuthentication
This rest API call works perfectly well.
When I register via this API I get the below response.
{
"key": "3735f13cd69051579156f98ffda338a2d7a89bb5"
}
I also want to include the user_id field in the response. How do I go about doing that. I tried extending the method get_response_data from class RegisterView(CreateAPIView): but unable to do so. Can someone please advise the best practice to achieve this. Code would be ideal. Thanks.
I want to use the rest-auth/registration/ url provided out of box by rest_auth.registration. I do not want to create a separate new URL for this.
My Settings.py as follows
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sites',
'sdAPI.apps.SdapiConfig',
'rest_framework',
'rest_framework.authtoken',
'rest_auth',
'rest_framework_swagger',
'rest_auth.registration',
'allauth',
'allauth.account',
'allauth.socialaccount',
'allauth.socialaccount.providers.facebook',
'allauth.socialaccount.providers.google',
'django_extensions',
]
# auth and allauth settings
LOGIN_REDIRECT_URL = '/'
SOCIALACCOUNT_QUERY_EMAIL = True
SOCIALACCOUNT_PROVIDERS = {
'facebook': {
'SCOPE': ['email', 'publish_stream'],
'METHOD': 'oauth2' # instead of 'oauth2'
}
}
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
)
}
SITE_ID = 1
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
REST_SESSION_LOGIN = False
My urls.py as follows
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^user/(?P<pk>[0-9]+)/$', views.UserDetail.as_view()),
url(r'^rest-auth/', include('rest_auth.urls')),
url(r'^rest-auth/registration/',include('rest_auth.registration.urls')),
]
I think you only need to override the TOKEN_SERIALIZER option in your REST_AUTH_SERIALIZERS configuration.
from rest_framework.authtoken.models import Token
class TokenSerializer(serializers.ModelSerializer):
class Meta:
model = Token
fields = ('key', 'user')
Then, set it in your settings.py as shown in the docs,
REST_AUTH_SERIALIZERS = {
'LOGIN_SERIALIZER': 'path.to.custom.LoginSerializer',
'TOKEN_SERIALIZER': 'path.to.custom.TokenSerializer',
...
}