What's the fix for this attribute error 'list' object has no attribute 'META' in Django. Am trying to access an api route of my Django rest framework - django-models

I can't access any api route of my django rest api. it used to work a few weeks ago. although it now throws the attribute error.
in settings.py
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# 'api',
'api.apps.ApiConfig',
'rest_framework',
'dashboard',
'import_export',
]
in views.py
# imports
from rest_framework.decorators import api_view
from rest_framework.response import Response
#api_view(['GET'])
def getRoutes(request):
routes = [
{
'Endpoint': '/api/questionnaire/',
'Method': 'GET',
'Body': None,
'description':'returns an array of questionnaire',
},
{
'Endpoint': '/api/questionnaire/id',
'Method': 'GET',
'Body': None,
'description':'returns a single questionnaire object',
},
{
'Endpoint': '/api/questionnaire/create',
'Method': 'POST',
'Body': {'body':""},
'description':'creates a new questionnaire with data sent in the new req',
},
{
'Endpoint': '/api/questionnaire/id/update',
'Method': 'PUT',
'Body': {'body':""},
'description':'updates existing questionnaire specific to id',
},
{
'Endpoint': '/api/questionnaire/id/delete',
'Method': 'DELETE',
'Body': None,
'description':'deletes an existing questionnaire',
}
]
return Response(routes)
in urls.py
path('routes/', views.getRoutes , name='routes')
i need to access my DRF api once i navigate to the specified url route. i have double-checked my url patterns , views but everything is just as it should be. could it be an issue with django rest framework version since it was working fine just a few weeks ago.?

Related

Django CORS request external redirect not allowed

I faced a problem during send GET request to a django view from react, and those view redirect to GOOGLE_AUTH_ENDPOINT., and this url hit a callback function. But after request from react, it give this error:
Access to fetch at "google auth url" (redirected from 'localhost:8000') from origin 'localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
view
class Glogin(APIView):
params = {
'client_id': CLIENT_ID,
'response_type': 'code',
'scope': 'openid email profile',
'redirect_uri': CALLBACK_DOMAIN,
'state': state,
}
if APPS_DOMAIN:
params['hd'] = APPS_DOMAIN
def get(self,request):
request.session['googleauth_csrf'] = state
request.session['next'] = request.META.get('HTTP_REFERER', None)
print('Here')
print(urlencode(self.params))
return HttpResponseRedirect("%s?%s" % (GOOGLE_AUTH_ENDPOINT, urlencode(self.params)))
#data = {'link':GOOGLE_AUTH_ENDPOINT, 'params':self.params}
#return Response(data)
ReactJs
static GLogIn() {
return fetch("http://127.0.0.1:8000/glogin/", {
//method: "POST",
method: "GET",
headers: {
"Content-Type": "application/json",
},
//body: JSON.stringify(body),
}).then((response) => response.json());
}
URL
urlpatterns = [
path('', include(router.urls)),
path('auth/', obtain_auth_token),
path('login/',views.LogInViewSet.as_view()),
path('logout/',views.LogOutViewSet.as_view()),
path('articles/',views.ArticlesView.as_view()),
path('articles/<int:pk>/',views.ArticlesView.as_view()),
path('glogin/',views.Glogin.as_view()),
path('callback/',views.Callback.as_view(), name='googleauth_callback'),
#path('articales/',views.ArticlesViewSet.as_view())
]
settings.py
CORS_ORIGIN_WHITELIST = (
'localhost:3000',
#'accounts.google.com',
#'accounts.google.com/o/oauth2/v2'
)
CORS_ALLOW_HEADERS = [
'accept',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
]
Put a hosts entry in the /etc/hosts file for 127.0.0.1
127.0.0.1 myfakedomain.local
Then add this to the CORS_ORIGIN_WHITELIST
'myfakedomain.local:8000',
Then you can access cors redirects. Chrome blocks them unless they are on special domains. Especially localhost.
Then send your browser to http://myfakedomain.local:8000

Facing issue with setting up http only cookie while using react js for frontend and django rest framework for backend

I started building a basic Authentication system with JWT token authentication using rest API and react js. But, I was facing an issue while setting my cookie from the Django views sent using rest_framework.response.Response object. Now, the problem is that in the Django server the cookie is set, but in this case, while integrated with react js it fails. Django server is running on port 8000 and react js on 3000.
#api_view(['POST'])
def login(request):
try:
username = request.data['username']
password = request.data['password']
user = authenticate(request=request, username=username, password=password)
if user:
refresh = RefreshToken.for_user(user)
response = Response()
response.data = {
"status": True,
"Access": str(refresh.access_token)
}
response.set_cookie(key='refreshtoken', value=(refresh), httponly=True, samesite=None)
return response
else:
return Response(FALSE_RESPONSE)
except Exception as e:
print(e)
return Response(FALSE_RESPONSE)
This is the axios request, I was making from the frontend side.
axios({
method: "POST",
url: "http://localhost:8000/user-api/login/",
data: {
username:username,
password:password
},
credentials: 'include',
withCredentials: true
})
.then(response => {
console.log(response)
if(response.data['status']) {
setAccessToken(response.data['Access'])
setIsAuthenticated(true)
setLoginModal(false)
} else {
alert("Error! Credentials doesn't match.")
}
})
.catch(error => {
console.log(error)
})
This axios request generates no errors and I was successfully getting the token, but the refresh token was not getting saved in the cookies.
# settings.py
CORS_ALLOWED_ORIGINS = [
"http://localhost:3000",
"http://127.0.0.1:3000"
]
CORS_ALLOW_CREDENTIALS = True
Help me with this issue!!

'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource

I am working on project using Django and React using Rest Framework. I have set CORS_ALLOW_ALL_ORIGINS=True in settings.py still i am getting error Access to XMLHttpRequest at 'http://127.0.0.1:8000/api/encrypt/' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I am using axios to post and get request. Suprisingly even after error post request is made but get request fails.
This is react file using axios
sendImage =()=> {
this.activateSpinner()
let formData = new FormData()
formData.append('to_be_hidden', this.state.files[0], this.state.files[0].name)
formData.append('used_to_hide', this.state.files[1], this.state.files[1].name)
axios.post('http://127.0.0.1:8000/api/encrypt/', formData, {
headers: {
'accept': 'application/json',
'content-type': 'multipart/form-data'
}
})
.then(resp=>{
this.getImageClass(resp)
console.log(resp.data.id)
})
.catch(err=>{
console.log("Code broke at send image")
console.log(err)
})
}
getImageClass =(obj)=> {
axios.get(`http://127.0.0.1:8000/api/encrypt/${obj.data.id}/`, {
headers: {
'accept': 'application/json',
}
})
.then(resp=>{
this.setState({recentImage:resp})
console.log(resp)
})
.catch(err=>{
console.log("Code broke at get image")
console.log(err)
})
this.deactivateSpinner()
}
ALLOWED_HOSTS=['*']
INSTALLED_APPS = [
'django.contrib.admin',
...
'corsheaders',
]
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
....
"corsheaders.middleware.CorsMiddleware",
]
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_METHODS = [
"DELETE",
"GET",
"OPTIONS",
"PATCH",
"POST",
"PUT",
]
CORS_ALLOW_HEADERS = [
"accept",
"accept-encoding",
"authorization",
"content-type",
"dnt",
"origin",
"user-agent",
"x-csrftoken",
"x-requested-with",
]
It's definitely the issue from the backend side, I mean Django.
CORS_ALLOW_ALL_ORIGINS=True Once you set the CORS_ALLOW_ALL_ORIGINS value, you also need to set the values for ALLOWED_HOSTS.
For instance
ALLOWED_HOSTS=['*']
Please take a look at the below links.
https://pypi.org/project/django-cors-headers/
https://dzone.com/articles/how-to-fix-django-cors-error

404 error/No Access-Control-Allow-Origin header message in Symfony 4 + React app. How to make the routing work?

I have created simple application and would like to deploy it on a server. I am going through this for the first time – so no previous experiences I could benefit from.
The problem in general:
The app has implemented React Router, but uses Symfony routing for calls to and from database. So for navigating through app tabs, React Router takes place, for fetching in/from DB I intended to use Symfony routes.
Everything works well when I am on the local server. But when I manually dragged and dropped files on the server the app breaks on the fetch requests.
React component code:
let targetUrl = `http://serverAddress.nazwa.pl/save`;
let request = new Request(targetUrl, {
body: formData,
method: "POST",
headers: {
"Access-Control-Request-Method": "POST, GET, OPTIONS",
"Origin": "http://mySimpleAppDomain.com.pl",
}
})
fetch(request)
.then((response) => response.json())
.then((response) => {
this.setState({
isListActive: false,
currentItems: [],
currentItemsCounter: 0
})
document.getElementById("defNavEl").classList.add("default")
})
.catch((error) => {
console.error('SAVE TO DB FETCH ERROR:', error);
});
Symfony Controller code:
**
* #Route("/save", name="save")
*/
public function save(Request $request)
{
$shoppingList = new ShoppingList();
$list = $request->request->all();
if (count($list) > 0) {
$em = $this->getDoctrine()->getManager();
$shoppingList->setCreationDate(new \DateTime());
$shoppingList->setName($list['name']);
unset($list['name']);
$shoppingList->setListItems($list);
$em->persist($shoppingList);
$em->flush();
$results = $em->getRepository(ShoppingList::class)->listAllShoppingLists();
$response = $this->json($results);
$response->headers->set('Access-Control-Allow-Origin', 'https://localhost:8006');
$response->headers->set('Content-Type', 'application/json');
return $response;
} else {
return new Response();
}
}
Nelmio CORS bundle configuration:
nelmio_cors:
defaults:
allow_credentials: false
allow_origin: []
allow_headers: []
allow_methods: []
expose_headers: []
max_age: 0
hosts: []
origin_regex: false
forced_allow_origin_value: ~
paths:
'^/': null
origin_regex: false
allow_origin: ['*']
allow_methods: ['*']
allow_headers: ['*']
expose_headers: ['Link']
max_age: 3600
Observations:
When I try to fetch data to DB I receive the following message in the console:
Access to fetch at 'http://example.nazwa.pl/save' from origin 'http://myappname.com.pl' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
This happens despite the fact that I have set ‘Access-Control-Allow-Origin' header in the action that is intended to handle the request.
When I send some test requests on the http://serverAddress.nazwa.pl/save via Postman, I get 404 error.
That seems to be at odds with the CORS policy message cited in he point 1).
What I tried (among others):
I tried to reorganize controller so that there is only one action responsible for different requests. But mysteriously it didn't work. It also doesn't seem to be good idea in terms of good practices.
Calling for help:
I am out of ideas for now. Perhaps it is something with .htaccess configuration (I have installed Apache Pack, which has generated it). I will appreciate any suggestions or ideas that could help me move forward.
Your Configuration is pointing to null at this line :
'^/': null
You need to have configuration related to your route and domain like this:
Feel free to change it to your needs and use .env config if it's symfony 4:
nelmio_cors:
defaults:
origin_regex: true
allow_origin: ['%env(CORS_ALLOW_ORIGIN)%']
allow_methods: ['GET', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE']
allow_headers: ['Content-Type', 'Authorization']
expose_headers: ['Link']
max_age: 3600
paths:
'^/save' :
allow_origin:
- '^http://serverAddress.nazwa.pl/'
- '^http://localhost:[0-9]+'
- '^http://serverAddress.nazwa.pl/save'
#allow_origin: ['*']
allow_credentials: true
allow_headers: ['Authorization', 'X-Requested-With', 'content-type','Content-Type', 'Accept', 'Origin', 'X-Custom-Auth']
allow_methods: ['POST', 'PUT', 'GET', 'DELETE','PATCH','OPTIONS']
max_age: 3600
'^/': null
The Paths array will take route and apply default configuration from above and then merge it with route specific configuration so you get exact config for each routes defined.
This example defaults all other routes to block cors requests except /save route which will allow domains or paths defined in array.
Note that : allow_origin: ['*'] will allow from all other domains to request resource which is not recommended unless it is a public api and any script can request to it.

axios POST request to strapi image upload [Internal Server Error]

I'm uploading an image to strapi using axios but the response is 500 error. However in Postman the request is 200
POSTMAN
AXIOS CODE
let bodyFormData = new FormData();
bodyFormData.append('files', this.state.avatar, this.state.avatar.name)
bodyFormData.append('ref', 'user')
bodyFormData.append('refId', getId())
bodyFormData.append('field', 'avatar')
bodyFormData.append('source', 'users-permmissions')
axios({
method: 'post',
url: `${strapi}/upload`,
headers: {
'Content-Type': 'multipart/form-data',
'Authorization': `Bearer ${withToken()}`,
},
data: bodyFormData,
}).then(res=>console.log(res.data)).catch(err=>{console.log(err.response.data.message)})
what's supposed to be the issue here?
Here's part of the strapi user model
{
"avatar": {
"model": "file",
"via": "related",
"plugin": "upload",
"required": false
}
}
The solution is to throw Axios in the trash. I struggled with this for a day of my life that I will never get back. There's a longish, years-old thread at https://github.com/axios/axios/issues/318 with people complaining about being unable to get multipart form uploads to work with Axios.
I switched to the request-promise module and got it to work within minutes, using the following simple code:
const fs = require("fs-extra");
const rp = require('request-promise');
let out = await rp({
method: 'POST',
uri: 'http://mystrapihost/upload',
formData: {
// Like <input type="text" name="ref">
'ref': "customer", // name of the Strapi data type, singular
'field': "attachments", // a field named "attachments" of type "Media"
'refId': "838e238949ewhd82e8938299e289e99", // strapi ID of object to attach to
// Like <input type="file" name="files">
"files": { // must be called "files" to be "seen" by Strapi Upload module
name: "myfile.pdf",
value: fs.createReadStream("/path/to/myfile.pdf"),
options: {
filename: "myfile.pdf",
contentType: 'application/pdf'
},
},
},
headers: {Authorization: 'Bearer myjwtgobbledygook123456'} // put your JWT code here
});
console.log(out);
Enjoy!!

Resources