I am creating a Django REST project.
I created a custom user model in which I used rest-knox for token authentication. For the login and register user endpoints I used custom views where I authenticate the user's by their knox token. For password_change endpoint I used django auth's views.
Here is the problem I am facing:
When I try password_change endpoint in browsable API; it redirects me again to login page and does nothing. However Knox token for the user is created and returned in JSON.
When I try the endpoint in Postman it gives CSRF token error since I cannot get the CSRF token.
I tried to create my own front-end page for changing password and sometimes the 'csrftoken' was returned in cookie table of chrome but not all the time. Since I get the user token with JSON response I set it to cookies on React.js and reach anytime I want. Yet, get method of react-cookie doesn't work for csrftoken and it is being set as undefined. Finally I tried to use axios library for my post request and set default header for 'csrftoken' but couldn't see any results. The front-end 'localhost:3000/change_password/' page just redirects to itself by adding passed parameters to the end of url.
views.py
from django.shortcuts import render
from rest_framework import viewsets, generics
from rest_framework.authtoken.models import Token
from rest_framework.response import Response
from knox.auth import TokenAuthentication
from knox.models import AuthToken
from rest_framework.permissions import IsAuthenticated, AllowAny
from .models import UserProfile
from .serializers import UserSerializer, LoginSerializer, KnoxSerializer, RegisterSerializer
from django.contrib.auth import views, decorators
from django.contrib.auth.decorators import user_passes_test
class UserListAPI(generics.ListAPIView):
authentication_classes = (TokenAuthentication,)
permission_classes = (AllowAny,)
queryset = UserProfile.objects.all()
serializer_class = UserSerializer
class UserDetailAPI(generics.RetrieveAPIView):
authentication_classes = (TokenAuthentication,)
permission_classes = (AllowAny,)
queryset = UserProfile.objects.all()
serializer_class = UserSerializer
lookup_field = 'username'
class LoginAPI(generics.GenericAPIView):
serializer_class = LoginSerializer
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.validated_data
token = AuthToken.objects.create(user)[1]
return Response({
"user": UserSerializer(user, context=self.get_serializer_context()).data,
"token": token
})
class RegisterAPI(generics.GenericAPIView):
serializer_class = RegisterSerializer
queryset = UserProfile.objects.all()
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.save()
return Response({
"user": UserSerializer(user, context=self.get_serializer_context()).data,
"token": AuthToken.objects.create(user)[1]
})
settings.py
import os
from decouple import config
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = config('SECRET_KEY')
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'knox',
'rest_framework.authtoken',
'accounts',
'rest_auth',
]
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',
]
ROOT_URLCONF = 'Book_Lib_Project.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'Book_Lib_Project.wsgi.application'
# Database
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# Password validation
# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.0/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/
STATIC_URL = '/static/'
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': ('knox.auth.TokenAuthentication',),
'DATETIME_FORMAT': ("%m/%d/%Y %H:%M:%S",),
'DEFAULT_PERMISSION_CLASSES':(
'rest_framework.permissions.AllowAny',),
}
AUTHENTICATION_BACKENDS = [
"django.contrib.auth.backends.ModelBackend",
# #"accounts.backends.EmailAuthenticationBackend",
]
PASSWORD_HASHERS = [
'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
'django.contrib.auth.hashers.Argon2PasswordHasher',
]
from datetime import timedelta
from rest_framework.settings import api_settings
REST_KNOX = {
'SECURE_HASH_ALGORITHM': 'cryptography.hazmat.primitives.hashes.SHA512',
'AUTH_TOKEN_CHARACTER_LENGTH': 64,
'TOKEN_TTL': timedelta(hours=10),
'USER_SERIALIZER': 'knox.serializers.UserSerializer',
'TOKEN_LIMIT_PER_USER': None,
'AUTO_REFRESH': False,
'EXPIRY_DATETIME_FORMAT': api_settings.DATETIME_FORMAT,
}
urls.py
from django.urls import path, include
from .views import UserListAPI, UserDetailAPI, LoginAPI, RegisterAPI, PasswordChangeAPI
from knox import views as knox_views
urlpatterns = [
path('logout/', knox_views.LogoutView.as_view(), name = "knox_logout"),
path('users/', UserListAPI.as_view()),
path('users/<str:username>/', UserDetailAPI.as_view()),
path('login/', LoginAPI.as_view()),
path('register/', RegisterAPI.as_view()),
path('', include('django.contrib.auth.urls')),
]
Index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import axios from 'axios';
axios.defaults.withCredentials = true
axios.defaults.baseURL = 'https://jsonplaceholder.typicode.com';
axios.defaults.headers.post['Content-Type'] = 'application/json';
axios.defaults.xsrfCookieName = 'csrftoken'
axios.defaults.xsrfHeaderName = 'X-CSRFToken'
axios.interceptors.request.use(request => {
console.log(request.headers);
// Edit request config
return request;
}, error => {
console.log(error);
return Promise.reject(error);
});
axios.interceptors.response.use(response => {
console.log(response);
// Edit response config
return response;
}, error => {
console.log(error);
return Promise.reject(error);
});
ReactDOM.render(<App />, document.getElementById('root'));
serviceWorker.unregister();
ChangePassword.js
import React, {Component} from 'react';
//import ReactDOM from 'react-dom';
import { withCookies } from 'react-cookie';
import './ChangePassword.css';
import Axios from 'axios'
class ChangePassword extends Component {
state = {
credentials: {
old_password: '',
new_password1: '',
new_password2: '',
},
token: this.props.cookies.get('usertoken'),
}
inputChanged = event => {
let cred = this.state.credentials;
cred[event.target.name] = event.target.value;
this.setState({credentials: cred});
}
pressedEnter = event => {
if (event.key === 'Enter') {
this.changePassword();
}
}
changePassword = event => {
Axios.post('http://127.0.0.1:8000/accounts/password_change/', this.state.credentials, {headers: {
'Authorization': `Token ${this.state.token}`
}})
.then(res => {
console.log(res);
window.location.href = "/";
})
.catch( error => console.log(error))
}
render() {
return (
<div className="Login">
<form onSubmit={this.changePassword}>
<label>Old Password</label>
<input type="text" name="old_password" value={this.state.credentials.email} onChange={this.inputChanged} onKeyPress={this.pressedEnter}/><br/>
<label>New Password</label>
<input type="password" name="new_password1" value={this.state.credentials.password} onChange={this.inputChanged} onKeyPress={this.pressedEnter}/><br/>
<label>Confirm New Password</label>
<input type="password" name="new_password2" value={this.state.credentials.password} onChange={this.inputChanged} onKeyPress={this.pressedEnter}/><br/>
<input type="submit" value="Change" data-test="submit" />
</form>
</div>
)
}
}
export default withCookies(ChangePassword);
I solved the problem, so here is the solution if anyone encounters with the same problem and looks here.
At first, I needed to use the domain as http://127.0.0.1:3000 instead of http://localhost:3000 because of the restrictions given in https://curl.haxx.se/rfc/cookie_spec.html (check the section named as DOMAIN). Also, making some change on setting.py file was required.
Added below information to my settings.py file
CORS_ORIGIN_WHITELIST = (
'http://127.0.0.1:3000',
)
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True
CORS_EXPOSE_HEADERS = (
'Access-Control-Allow-Origin: http://127.0.0.1:3000',
)
Changed my axios configuration in index.js to
axios.defaults.withCredentials = true
axios.defaults.baseURL = 'http://127.0.0.1:8000/';
axios.defaults.xsrfCookieName = 'csrftoken'
axios.defaults.xsrfHeaderName = 'x-csrftoken'
A proper way to make a post for login page is like:
Axios.post('http://127.0.0.1:8000/accounts/login/', this.state.credentials).then(res => {
console.log(res);
this.props.cookies.set('usertoken', res.data.token);
// Used token based authentication. A token is returned from backend in JSON format.
}).catch( error => console.log(error))
Related
I've been struggling for over a week with this issue.
This is definitely an authentication problem. I implemented social google login with dj-rest-autj, all-auth and simple JWT. Credential flow is, first, getting access_token from google which is done in frontend. Second, sendind a request to an endpoint 'api/user-google' with the access_token, which returns JWT access_token and refresh_token, which is working fine. Finally sending a request to get user detail, but returned the error message.
Here is the request to get user detail.
await axios.get( `/api/user/${UID}`,{
withCredentials: true,
headers: {
"Authorization": 'JWT ' + `${access_token}`,
"Content-Type":"aplication/json"
}
})
below are relevant source codes.
settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'user',
'rest_framework.authtoken',
'django.contrib.sites',
'dj_rest_auth',
'dj_rest_auth.registration',
'allauth',
'allauth.account',
'allauth.socialaccount',
'allauth.socialaccount.providers.google',
'rest_framework',
'rest_framework.authtoken'
]
# allauth google provisder config
SOCIALACCOUNT_PROVIDER = {
'google': {
'SCOPE': [
'profile',
'email'
],
'AUTH_PARAMS': {
'access_type': 'online'
},
}
}
SOCIALACCOUNT_EMAIL_VARIFICATION = 'none'
SOCIALACCOUNT_EMAIL_REQUIRED = False
# dj-rest-auth config
SITE_ID = 1
JWT_AUTH_SECURE = True
REST_USE_JWT = True
REST_AUTH_SERIALIZER = {
'USER_DETAILS_SERIALIZER' :'user.serializers.UserSerializer',
}
JWT_AUTH_COOKIE = 'access_token'
JWT_AUTH_REFRESH_COOKIE = 'refresh-token'
# auth user model confi
AUTH_USER_MODEL = 'user.User'
# simple_JWT config
SIMPLE_JWT = {
'AUTH_HEADER_TYPES': ('JWT'),
'ACCESS_TOKEN_LIFETIME': timedelta(days=7),
'ROTATE_REFRESH_TOKENS' : True,
'BLACKLIST_AFTER_ROTATION': True,
'UPDATE_LAST_LOGIN': True,
'USER_ID_FIELD': 'UID',
'USER_ID_CLAIM': 'user_id'
}
# rest framework config
REST_FRAMEWORK = {
'DEFAULT_AUTENTICATION_CLASSES' : (
'dj_rest_auth.jwt_auth.JWTCookieAuthentication',
),
'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'],
'DATETIME_FORMAT': "%Y-%m-%d %H:%M",
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE':8,
}
user/urls.py
from django.urls import path
from user.apis import UserList, GoogleLogin, UserDetail
urlpatterns = [
path('user/', UserList.as_view()),
path('user-google/', GoogleLogin.as_view()),
path('user/<UID>', UserDetail.as_view()),
]
user/views.py
class GoogleLogin(SocialLoginView):
adapter_class = GoogleOAuth2Adapter
client_class = OAuth2Client
class UserDetail(generics.RetrieveUpdateAPIView ):
pagination_class = None
queryset = User.objects.all()
serializer_class = UserStrageSerializer
lookup_field = 'UID'
user/serializers.py
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = "__all__"
def create(self, validated_data):
user = User.objects.create_user(
validated_data["username"],
validated_data['email'],
validated_data['password']
)
return user
core.urls.py
from django.contrib import admin
from django.urls import path,include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('api/',include('user.urls')),
path('api/auth/',include('dj_rest_auth.urls')),
path('api/auth/registration/',include('dj_rest_auth.registration.urls')),
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
if settings.DEBUG:
import debug_toolbar
urlpatterns = [
path('__debug__/', include(debug_toolbar.urls)),
] + urlpatterns
My understanding is that
'DEFAULT_AUTENTICATION_CLASSES' : (
'dj_rest_auth.jwt_auth.JWTCookieAuthentication',
),
the above in settings means if request headers include access_token, the user will be isAuthenticated which trigger the 'rest_framework.permissions.IsAuthenticated'
like below
'DEFAULT_PERMISSION_CLASSES' : [
'rest_framework.permissions.IsAuthenticated'
],
So hitting endpoint without access_token returns error "Authentication credentials were not provided", but with access_token should return values from DB, but it is not like this in my case.
any suggestion, please?
**
If I set authentication_classes into UserDetail view directory, returns the expected data.
from dj_rest_auth.jwt_auth import JWTCookieAuthentication as JWT
class UserDetail(generics.RetrieveUpdateAPIView ):
pagination_class = None
queryset = User.objects.all()
authentication_classes = ([JWT]) #added
serializer_class = UserStrageSerializer
lookup_field = 'UID'
but this doesn't solve the isAthenticated problem.
I have created a vue and DRF application, which is working fine locally, it sets access, refresh and csrf token in cookies on login and so all of the isAuthenticated routes work fine.
But i handed it over to the person who's meant to deploy this on vps and now it doesn't set cookie on login. I'm able to login, but since no cookie is set, refreshing it logs me out and all routes give 401 error.
These are my django settings, removing secret_key here:
import os
from pathlib import Path
from datetime import timedelta
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ['*']
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'rest_framework_api_key',
'rest_framework_simplejwt.token_blacklist',
'corsheaders',
'django_filters',
'api'
]
AUTH_USER_MODEL = 'api.User'
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.AllowAllUsersModelBackend',
)
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',
]
CORS_ALLOW_ALL_ORIGINS = True
CORS_ALLOW_HEADERS = [
"accept",
"accept-encoding",
"authorization",
"content-type",
"dnt",
"origin",
"user-agent",
"x-csrftoken",
"x-requested-with",
"fxbNh4",
]
# CORS_ALLOWED_ORIGINS = [
# "http://localhost:8080"
# ]
# CORS_ALLOWED_ORIGINS = [
# 'http://34.67.29.99',
# ]
CORS_ALLOW_CREDENTIALS = True
ROOT_URLCONF = 'InstaBackend.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR)],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'InstaBackend.wsgi.application'
# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# Password validation
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'Asia/Karachi'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': (
'django_filters.rest_framework.DjangoFilterBackend',
),
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 12,
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated'
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'api.authenticate.CustomAuthentication',
),
'DATETIME_FORMAT': "%Y-%m-%d %H:%M:%S",
}
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(days=1),
'REFRESH_TOKEN_LIFETIME': timedelta(days=7),
'ROTATE_REFRESH_TOKENS': False,
'BLACKLIST_AFTER_ROTATION': True,
'UPDATE_LAST_LOGIN': False,
'ALGORITHM': 'HS256',
'SIGNING_KEY': SECRET_KEY,
'VERIFYING_KEY': None,
'AUDIENCE': None,
'ISSUER': None,
'AUTH_HEADER_TYPES': ('Bearer',),
'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION',
'USER_ID_FIELD': 'id',
'USER_ID_CLAIM': 'user_id',
'USER_AUTHENTICATION_RULE': 'rest_framework_simplejwt.authentication.default_user_authentication_rule',
'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
'TOKEN_TYPE_CLAIM': 'token_type',
'JTI_CLAIM': 'jti',
'SLIDING_TOKEN_REFRESH_EXP_CLAIM': 'refresh_exp',
'SLIDING_TOKEN_LIFETIME': timedelta(minutes=5),
'SLIDING_TOKEN_REFRESH_LIFETIME': timedelta(days=1),
'AUTH_ACCESS_COOKIE': 'access_token', # Cookie name. Enables cookies if value is set.
'AUTH_REFRESH_COOKIE': 'refresh_token', # Cookie name. Enables cookies if value is set.
'AUTH_CSRF_ACCESS_COOKIE': 'csrf_access_token', # Cookie name. Enables cookies if value is set.
'AUTH_CSRF_REFRESH_COOKIE': 'csrf_refresh_token', # Cookie name. Enables cookies if value is set.
'AUTH_COOKIE_DOMAIN': None, # A string like "example.com", or None for standard domain cookie.
'AUTH_COOKIE_SECURE': False, # Whether the auth cookies should be secure (https:// only).
'AUTH_COOKIE_HTTP_ONLY': False, # Http only cookie flag.It's not fetch by javascript.
'AUTH_COOKIE_PATH': '/', # The path of the auth cookie.
'AUTH_COOKIE_SAMESITE': None, # Whether to set the flag restricting cookie leaks on cross-site requests.
# This can be 'Lax', 'Strict', or None to disable the flag.
}
# CSRF_COOKIE_DOMAIN = '34.67.29.99'
# # CSRF_COOKIE_SECURE = True
# # USE_X_FORWARDED_HOST = True
# # SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
# CSRF_TRUSTED_ORIGINS = ['http://34.67.29.99/','http://34.67.29.99',]
# CSRF_COOKIE_SAMESITE = 'Lax'
# CSRF_COOKIE_HTTPONLY = False
# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
This is how I set cookies :
def set_access_cookies(response, access_token):
response.set_cookie(
key=settings.SIMPLE_JWT['AUTH_ACCESS_COOKIE'],
value=access_token,
expires=settings.SIMPLE_JWT['ACCESS_TOKEN_LIFETIME'],
secure=settings.SIMPLE_JWT['AUTH_COOKIE_SECURE'],
httponly=settings.SIMPLE_JWT['AUTH_COOKIE_HTTP_ONLY'],
samesite=settings.SIMPLE_JWT['AUTH_COOKIE_SAMESITE']
)
def set_refresh_cookies(response, refresh_token):
response.set_cookie(
key=settings.SIMPLE_JWT['AUTH_REFRESH_COOKIE'],
value=refresh_token,
expires=settings.SIMPLE_JWT['REFRESH_TOKEN_LIFETIME'],
secure=settings.SIMPLE_JWT['AUTH_COOKIE_SECURE'],
httponly=settings.SIMPLE_JWT['AUTH_COOKIE_HTTP_ONLY'],
samesite=settings.SIMPLE_JWT['AUTH_COOKIE_SAMESITE']
)
This is my login_view:
from django.middleware import csrf
from rest_framework.views import APIView
from rest_framework.response import Response
from django.contrib.auth import authenticate
from rest_framework import status
from api.util import (set_access_cookies, set_refresh_cookies, get_tokens_for_user, combine_role_permissions,
extract_patient_role)
from api.serializers import UserSerializer, RoleSerializer
from django.utils import timezone
from api.models import User
from rest_framework_api_key.permissions import HasAPIKey
from rest_framework.permissions import AllowAny
class LoginView(APIView):
authentication_classes = ()
permission_classes = (HasAPIKey,)
# permission_classes = (AllowAny,)
def post(self, request):
try:
data = request.data
response = Response()
username = data.get('username', None)
password = data.get('password', None)
try:
User.objects.get(email = username)
except User.DoesNotExist:
return Response({"msg": "User Credentails don't exist ! "}, status=status.HTTP_400_BAD_REQUEST)
user = authenticate(username=username, password=password)
if user.is_approved:
if user is not None:
role, roles = extract_patient_role(user.roles.all())
permissions = combine_role_permissions(roles)
data = get_tokens_for_user(user, is_patient=False)
set_access_cookies(response, data['access'])
set_refresh_cookies(response, data['refresh'])
csrf.get_token(request)
data = UserSerializer(user, context={'request': request}).data
data['roles'] = RoleSerializer(roles, many=True).data
data['permissions'] = permissions
response.status_code = status.HTTP_200_OK
response.data = {"msg": "Login successfully", "user": data}
user.last_login = timezone.now()
user.save()
return response
else:
return Response({"msg": "Invalid credentials"}, status=status.HTTP_404_NOT_FOUND)
else:
return Response({"msg": "Please verify account to log in"}, status=status.HTTP_400_BAD_REQUEST)
except Exception as e:
print(e)
return Response({"msg": "Unable to Login"}, status=status.HTTP_400_BAD_REQUEST)
This is the axios instance for logging in:
import Vue from "vue";
import axios from "axios";
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== "") {
var cookies = document.cookie.split(";");
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i].trim();
if (cookie.substring(0, name.length + 1) === name + "=") {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
const axiosIns2 = axios.create({
baseURL: process.env.VUE_APP_API,
withCredentials: true,
xsrfCookieName: "csrftoken",
xsrfHeaderName: "X-CSRFTOKEN",
headers: {
"X-CSRFTOKEN": getCookie("csrftoken"),
Authorization: "Api-Key " + process.env.VUE_APP_KEY,
},
});
Vue.prototype.$http = axiosIns2;
export default axiosIns2;
And this is the axios instance for other authenticated requests:
import Vue from "vue";
import axios from "axios";
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== "") {
var cookies = document.cookie.split(";");
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i].trim();
if (cookie.substring(0, name.length + 1) === name + "=") {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
const axiosIns = axios.create({
baseURL: process.env.VUE_APP_API,
withCredentials: true,
xsrfCookieName: "csrftoken",
xsrfHeaderName: "X-CSRFTOKEN",
headers: {
"X-CSRFTOKEN": getCookie("csrftoken"),
},
});
const COOKIE_EXPIRED_MSG = "Token is invalid or expired";
axiosIns.interceptors.response.use(
(response) => {
return response;
},
async (error) => {
let error_message = null;
if (error.response.data.messages) {
error_message = error.response.data.messages[0].message;
}
switch (error.response.status) {
case 401:
if (!error.config.retry && error_message === COOKIE_EXPIRED_MSG) {
error.config.retry = true;
// axiosIns.defaults.xsrfCookieName = "csrf_refresh_token";
await axiosIns.post("/refresh");
// axiosIns.defaults.xsrfCookieName = "csrf_access_token";
return axiosIns(error.config);
} else {
throw new Error("Error");
}
break;
default:
break;
}
return Promise.reject(error);
}
);
Vue.prototype.$http = axiosIns;
export default axiosIns;
VPS OS Details:
Ubuntu 18.04.6
I currently don't have access to VPS, i believe this issue is due to SIMPLE_JWT settings in settings.py.
The project runs perfectly fine with these settings locally, but it doesn't send cookies on login when hosted. It does give 200 on login though.
Hosted Via:
Nginx , Gunicorn
The backend and frontend are hosted on 2 different hosts,
backend at : http://34.67.29.99:8080/
Frontend at : http://instasearch.convpho.com/login
I am using Django Rest Framework and OpenStack (DevStack deployed on a Virtual Machine on my local PC) to create APIs which will run methods provided by OpenStack SDK and return the response in JSON format.
However, while fetching(GET Request) a list of Servers created on OpenStack Cloud Platform, the Response for the first time after starting the Django Server is proper and desired, but after first GET Request, all GET requests sent are returning an empty List as the Response.
It must be noted that I have not changed anything in the code or in the Endpoint(URL), the same scenario keeps on repeating when I restart the Django Server, desired GET Response on first Request and Empty List for all the GET Requests onward.
I do not have any models of my own in models.py.
First GET Request Response:-
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
[
{
"name": "test_shell",
"image": "openstack.image.v2.image.Image(id=b6019f25-6f6d-4fd2-9fb8-14d50a07d2c0, properties={'links': [{'rel': 'bookmark', 'href': 'http://192.168.56.101/compute/images/b6019f25-6f6d-4fd2-9fb8-14d50a07d2c0'}]})",
"flavor": "openstack.compute.v2.flavor.Flavor(vcpus=1, ram=128, disk=1, OS-FLV-EXT-DATA:ephemeral=0, swap=0, original_name=m1.nano, extra_specs={'hw_rng:allowed': 'True'})",
"networks": null,
"status": "ACTIVE",
"power_state": "1"
},
{
"name": "ins_code_4",
"image": "openstack.image.v2.image.Image(id=b6019f25-6f6d-4fd2-9fb8-14d50a07d2c0, properties={'links': [{'rel': 'bookmark', 'href': 'http://192.168.56.101/compute/images/b6019f25-6f6d-4fd2-9fb8-14d50a07d2c0'}]})",
"flavor": "openstack.compute.v2.flavor.Flavor(vcpus=1, ram=128, disk=1, OS-FLV-EXT-DATA:ephemeral=0, swap=0, original_name=m1.nano, extra_specs={'hw_rng:allowed': 'True'})",
"networks": null,
"status": "SHUTOFF",
"power_state": "4"
},
{
"name": "ins_code_3",
"image": "openstack.image.v2.image.Image(id=b6019f25-6f6d-4fd2-9fb8-14d50a07d2c0, properties={'links': [{'rel': 'bookmark', 'href': 'http://192.168.56.101/compute/images/b6019f25-6f6d-4fd2-9fb8-14d50a07d2c0'}]})",
"flavor": "openstack.compute.v2.flavor.Flavor(vcpus=1, ram=128, disk=1, OS-FLV-EXT-DATA:ephemeral=0, swap=0, original_name=m1.nano, extra_specs={'hw_rng:allowed': 'True'})",
"networks": null,
"status": "SHUTOFF",
"power_state": "4"
}
]
GET Response after first Request:-
HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
[]
Django Code:-
Root settings.py
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-#gd5-6=)lwq4&bo(gywzy7ftic+5r!hgs$(%1gyqbt=pbwk=*a'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'api',
]
# Custom by me
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
}
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',
]
ROOT_URLCONF = 'cloudhome.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [ BASE_DIR / "templates" ],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'cloudhome.wsgi.application'
# Database
# https://docs.djangoproject.com/en/4.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# Password validation
# https://docs.djangoproject.com/en/4.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/4.0/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.0/howto/static-files/
STATIC_URL = 'static/'
STATICFILES_DIRS = [
BASE_DIR / "static"
]
STATIC_ROOT = "static_root"
# Default primary key field type
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
Root urls.py:-
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
path('api/', include('api.urls', namespace="api")),
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
App "api" urls.py:-
from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from api import views
app_name = "api"
urlpatterns = [
path('servers/', views.ServerList.as_view()),
path('servers/<slug:pk>/', views.ServerDetail.as_view()),
]
urlpatterns = format_suffix_patterns(urlpatterns)
App "api" views.py:-
from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt
from requests import request
from rest_framework.parsers import JSONParser
from api.serializers import ServerSerializer
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import generics
import openstack
from openstack import connection
from rest_framework import authentication, permissions
from rest_framework.permissions import IsAuthenticated
openstack.enable_logging(debug=True)
conn=connection.Connection(auth_url='http://192.168.56.101/identity/v3',
project_name='admin',username='admin',
password='nomoresecret',
user_domain_id='default',
project_domain_id='default', verify=False)
class ServerList(generics.ListAPIView):
queryset = conn.compute.servers()
serializer_class = ServerSerializer
permission_classes = [permissions.IsAuthenticated]
class ServerDetail(generics.RetrieveAPIView):
queryset = conn.compute.servers()
serializer_class = ServerSerializer
permission_classes = [permissions.IsAuthenticated]
App "api" serializers.py:-
import openstack
from openstack import connection
from requests import Response
from rest_framework import serializers
from rest_framework import status
openstack.enable_logging(debug=True)
conn=connection.Connection(auth_url='http://192.168.56.101/identity/v3',
project_name='admin',username='admin',
password='nomoresecret',
user_domain_id='default',
project_domain_id='default', verify=False)
class ServerSerializer(serializers.Serializer):
instance_id = serializers.CharField(read_only=True)
name = serializers.CharField(max_length=100)
image = serializers.CharField(max_length=500)
fixed_ip = serializers.IPAddressField(read_only=True)
floating_ip = serializers.IPAddressField(required=False, allow_blank=True)
flavor = serializers.CharField(max_length=500)
networks = serializers.CharField(max_length=500)
key_pair = serializers.CharField(max_length=100, required=False, allow_blank=True)
status = serializers.CharField(max_length=20, read_only=True)
power_state = serializers.CharField(max_length=20, read_only=True)
console_url = serializers.URLField(max_length=100, read_only=True)
def create(self, validated_data):
serverCreated = conn.compute.create_server(name=validated_data["instance_name"], image_id=validated_data["image_id"],
flavor_id=validated_data["flavor_id"], networks=[{"uuid": validated_data["network_id"]}])
serverWait = conn.compute.wait_for_server(serverCreated)
print(serverWait.access_ipv4)
return serverWait
Kindly help me to resolve this issue and feel free to suggest changes to make this code more efficient. Thanks in advance.
The following pages are the code of projects:
If i am using token = jwt.encode(payload,'secret', algorithm='HS256').decode('utf-8') statement
then
'str' object has no attribute 'decode'
error is occuring. Also, when I am removing and using it without .decode('utf-8') and proceeding with the further code. it is working fine. But when I am applying payload = jwt.decode(token, 'secret', algorithm=['HS256'])
then
It is required that you pass in a value for the "algorithms" argument when calling decode()"
This above-mentioned error is occurring. Please Help me to rectify this error. This is the mentioned error that saying algorithms argument when calling decode() error should be rectified.
View Page:
from django.http import request, response
from django.shortcuts import render
from rest_framework import serializers
from rest_framework.views import APIView
from myusers.serializers import UserSerializer
from rest_framework.exceptions import AuthenticationFailed
from rest_framework.response import Response
from .models import User
import jwt, datetime
# Create your views here.
class RegisterView(APIView):
def post(self,request):
serializer = UserSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data)
class LoginView(APIView):
def post(self,request):
email=request.data['email']
password = request.data['password']
user = User.objects.filter(email=email).first()
if user is None:
raise AuthenticationFailed('User Not Found!!!')
if not user.check_password(password):
raise AuthenticationFailed('Incorrect Password!!!')
payload={
'id':user.id,
'exp':datetime.datetime.utcnow() + datetime.timedelta(minutes=60),
'iat':datetime.datetime.utcnow()
}
token = jwt.encode(payload,'secret', algorithm='HS256').decode('utf-8')
response = Response()
response.data={
"jwt":token
}
response.set_cookie(key='jwt', value=token, httponly=True)
return response
class Userview(APIView):
def get(self,request):
token = request.COOKIES.get('jwt')
if not token:
raise AuthenticationFailed('User Authentication Failed!!!')
try:
payload = jwt.decode(token, 'secret', algorithm=['HS256'])
except jwt.ExpiredSignatureError:
raise AuthenticationFailed('Unauthenticated!')
user = User.objects.filter(id = payload['id']).first()
serializer = UserSerializer(user)
return Response(serializer.data)
class LogoutView(APIView):
def post(self, request):
response = Response()
response.delete_cookie('jwt')
response.data = {
'message': 'success'
}
return response
Serializer Page:
from django.db.models import fields
from rest_framework import serializers
from .models import User
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['id', 'name','email','password']
extra_kwargs={
'password' : {'write_only':True}
}
def create(self, validated_data):
password = validated_data.pop('password',None)
instance = self.Meta.model(**validated_data)
if password is not None:
instance.set_password(password)
instance.save()
return instance
Model Page:
from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.
class User(AbstractUser):
name = models.CharField(max_length=255)
email = models.CharField(max_length=250, unique=True)
password = models.CharField(max_length=255)
username = None
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
Urls page:
from django.urls import path
from .views import RegisterView, LoginView, Userview
urlpatterns = [
path('register',RegisterView.as_view()),
path('login',LoginView.as_view()),
path('user',Userview.as_view()),
path('logout',Userview.as_view()),
]
Setting Page:
"""
Django settings for login project.
Generated by 'django-admin startproject' using Django 4.0.1.
For more information on this file, see
https://docs.djangoproject.com/en/4.0/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.0/ref/settings/
"""
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-k02ug7k7bm-q0cgy4uini(mol=__ye-cm)$c1q+utmhg86ds$7'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'myusers',
'rest_framework',
'corsheaders'
]
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',
]
ROOT_URLCONF = 'login.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'login.wsgi.application'
# Database
# https://docs.djangoproject.com/en/4.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# Password validation
# https://docs.djangoproject.com/en/4.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/4.0/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.0/howto/static-files/
STATIC_URL = 'static/'
AUTH_USER_MODEL = 'myusers.User'
# Default primary key field type
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True
You're missing an 's', the parameter is called "algorithms" in the decode function:
payload = jwt.decode(token, 'secret', algorithms=['HS256'])
and you're also passing an array of possible values.
When you call encode, the parameter is "algorithm" and only takes a single value.
The reason is that during encoding (i.e signing), you have to use explicitly one algorithm, because a token can only be signed using one algorithm. But during decoding (verifying), you tell the function which algorithms you accept.
Another solution is to downgrade the PyJWT version to 1.7.1, so you wouldn't need to pass the "algorithms" argument.
Like this:
jwt.decode(encoded, verify=False)
I had to pass
verify=False, options={'verify_signature': False} in order to get it working.
When working on REST browsable API the responses work fine but when I started working on postman to integrate with front end on the other side the respond become:
{
"detail": "CSRF Failed: CSRF cookie not set."
}
I tried everything to solve this error but nothing change, and checked every question here on CSRF token but still didn't work
These are my codes:
views.py:
from django.shortcuts import render
from django.http import JsonResponse
from rest_framework.response import Response
from rest_framework import status
from User.serializers import UserDataSerializer, ImageSerializer
from rest_framework.views import APIView
from rest_framework import generics
from User.models import UserData,Image
from django.contrib.auth.models import User
from django.contrib.auth import authenticate, login, logout
from rest_framework.renderers import TemplateHTMLRenderer
from django.views.decorators.csrf import csrf_exempt
#csrf_exempt
class Signup(APIView):
def post(self, request, format = None):
serializer = UserDataSerializer(data = request.data)
if(serializer.is_valid()):
user = User.objects.create_user(
username = serializer.data['username'],
first_name = serializer.data['first_name'],
last_name = serializer.data['last_name'],
email = serializer.data['email'],
password = serializer.data['password'],
)
#add the name because it is not with create_user method
# user.name = serializer.data['name']
# user.save()
login(request, user)
print ("logged")
text = {'valid' : True , 'errors' :"ur password"+serializer.data['password']}
return JsonResponse(serializer.data)
else:
return JsonResponse(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class Login(APIView):
def post(self, request):
username = request.data.get('username')
password = request.data.get('password')
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
serializer = UserDataSerializer(user)
return JsonResponse(serializer.data, status=status.HTTP_302_FOUND)
else:
text = {'valid' : False , 'errors' : "Invalid Username or Password"}
return Response(text, status=status.HTTP_401_UNAUTHORIZED)
class Logout(APIView):
def get(self, request):
logout(request)
return Response({"valid": True}, status=status.HTTP_200_OK)
class ImageUpload(generics.CreateAPIView):
queryset = Image.objects.all()
serializer_class = ImageSerializer
settings.py:
"""
Django settings for app project.
Generated by 'django-admin startproject' using Django 1.10.3.
For more information on this file, see
https://docs.djangoproject.com/en/1.10/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.10/ref/settings/
"""
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'baz^+ip1ik4_fla*zg$9q#37e(5jg6tmnwzj4btqw#nw=si)+('
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
CSRF_COOKIE_SECURE = False
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'User.apps.UserConfig',
'rest_framework',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
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',
]
ROOT_URLCONF = 'app.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
# 'django.core.context_processors.csrf',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'app.wsgi.application'
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.AllowAny',),
}
# Database
# https://docs.djangoproject.com/en/1.10/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'ImageSearchDB',
'USER': 'root',
'PASSWORD': '1234',
'HOST': 'localhost',
'PORT': '',
'OPTIONS': {
'init_command': 'SET default_storage_engine=INNODB',
}
}
}
# Password validation
# https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# AUTHENTICATION_BACKENDS = (
# 'app.User.backends.EmailOrUsernameModelBackend',
# 'django.contrib.auth.backends.ModelBackend'
# )
# Internationalization
# https://docs.djangoproject.com/en/1.10/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.10/howto/static-files/
STATIC_URL = '/static/'
MEDIA_ROOT = os.path.join(BASE_DIR,'media')
MEDIA_URL = 'media/'
urls.py
from django.conf.urls import url
from User import views
from rest_framework.urlpatterns import format_suffix_patterns
urlpatterns = [
url(r'^login/?$', views.Login().as_view()),
url(r'^signup/?$', views.Signup().as_view()),
url(r'^logout/?$', views.Logout().as_view()),
url(r'^trail/?$', views.ImageUpload().as_view())
]
urlpatterns = format_suffix_patterns(urlpatterns) #no need
you have to use ensure_csrf_cookie decorator in the urls like this
from django.views.decorators.csrf import ensure_csrf_cookie
urlpatterns = [
url(r'^login/?$', ensure_csrf_cookie(views.Login().as_view())),
]
Also you need to add all of your CORS settings