Vuejs error 401 Unauthorized from DRF api - django

Vue Js error (401 Unauthorized)
Vue Js Error: 401 Image
Software Used-
DRF
Vuejs
while calling DRF api in Vue js (using axios) unbale to get data.
below code in App.vue
export default {
name: 'App',
components: {
'Header': Header,
'Footer': Footer,
'Navbar': Navbar
},
data () {
return {
info: []
}
},
mounted () {
var self = this
axios.get('http://127.0.0.1:8000/management/api/list/')
.then(function (res) {
self.info = res.data
console.log('Data: ', res.data)
})
.catch(function (error) {
console.log('Error: ', error)
})
}

You are requesting to an API which is protected and need authorization credentials to be available.
If you are using DRF token-management systems, you should first get a token from proper API endpoint. then pass this token via Authorization header in request.
For example if you are using jwt token management system in django, then you should send requests like this:
axios.get('http://127.0.0.1:8000/management/api/list/', { Authorization: `jwt ${token}`})
.then(function (res) {
self.info = res.data
console.log('Data: ', res.data)
})
.catch(function (error) {
console.log('Error: ', error)
})
Remember it really depends on your Authentication backend you are using. So if you can give more details about how you implemented your django DRF APIs, I guess we all can help you much better.

Related

AWS Amplify post request fails with "status code 403 at node_modules/axios"

I configured and initialized AWS Amplify for my ReactNative/Expo app and added a REST Api. Im new to AWS in general, but im assuming that once I add the API, my project is populated with amplify/backend folders and files and is ready for consumption.
So i tried to create a simple post request to create an item in my DynamoDB table with
import { Amplify, API } from "aws-amplify";
import awsconfig from "./src/aws-exports";
Amplify.configure(awsconfig);
const enterData = async () => {
API.post("API", "/", {
body: {
dateID: "testing",
},
headers: {
Authorization: `Bearer ${(await Auth.currentSession())
.getIdToken()
.getJwtToken()}`
}
})
.then((result) => {
// console.log(JSON.parse(result));
})
.catch((err) => {
console.log(err);
});
};
const signIn = async () => {
Auth.signIn('test#test.com', 'testpassword')
.then((data) => {
console.log(data)
enterData() //enterData is attempted after signin is confirmed.
})
.catch((err) => {
console.log(err)
})
}
signIn()
I did not touch anything else in my project folder besides including the above in my App.tsx because im unsure if i need to and where. I got a 403 error code and it "points" to the axios package but im not sure if issue is related to aws integration.
I configured the REST Api with restricted access where Authenticated users are allowed to CRUD, and guests are allowed to Read. How could I even check if I am considered an "Authorized User" .
Yes, AWS Amplify API category uses Axios under the hood so axios is related to your problem.
Probably you get 403 because you didn't authorized, for Rest API's you need to set authorization headers,
I don't know how is your config but you can take help from this page. Please review the "Define Authorization Rules" section under the API(REST) section.
https://docs.amplify.aws/lib/restapi/authz/q/platform/js/#customizing-http-request-headers
To check authorization methods, you can use "Auth" class like that also you can see auth class usage in the above link.
import { Amplify, API, Auth } from "aws-amplify";
https://aws-amplify.github.io/amplify-js/api/classes/authclass.html

How to block external requests to a NextJS Api route

I am using NextJS API routes to basically just proxy a custom API built with Python and Django that has not yet been made completely public, I used the tutorial on Vercel to add cors as a middleware to the route however it hasn't provided the exact functionality I wanted.
I do not want to allow any person to make a request to the route, this sort of defeats the purpose for but it still at least hides my API key.
Question
Is there a better way of properly stopping requests made to the route from external sources?
Any answer is appreciated!
// Api Route
import axios from "axios";
import Cors from 'cors'
// Initializing the cors middleware
const cors = Cors({
methods: ['GET', 'HEAD'],
allowedHeaders: ['Content-Type', 'Authorization','Origin'],
origin: ["https://squadkitresearch.net", 'http://localhost:3000'],
optionsSuccessStatus: 200,
})
function runMiddleware(req, res, fn) {
return new Promise((resolve, reject) => {
fn(req, res, (res) => {
if (res instanceof Error) {
return reject(res)
}
return resolve(res)
})
})
}
async function getApi(req, res) {
try {
await runMiddleware(req, res, cors)
const {
query: { url },
} = req;
const URL = `https://xxx/api/${url}`;
const response = await axios.get(URL, {
headers: {
Authorization: `Api-Key xxxx`,
Accept: "application/json",
}
});
if (response.status === 200) {
res.status(200).send(response.data)
}
console.log('Server Side response.data -->', response.data)
} catch (error) {
console.log('Error -->', error)
res.status(500).send({ error: 'Server Error' });
}
}
export default getApi
Sorry for this late answer,
I just think that this is the default behaviour of NextJS. You are already set, don't worry. There is in contrast, a little bit customization to make if you want to allow external sources fetching your Next API

Django - why am i not authenticated after logging in from Axios/AJAX?

I'm building a separated VueJS/Django app where Django will communicate with the Vue frontend using JSON. In order to be able to use the standard session authentication and django-allauth i will deploy the two apps on the same server and on the same port.
Here is my problem: after i log in from the Vue app using Axios, i don't receive any response but i notice that a session is created on the db, so i'm assuming that i'm getting logged in. But if i try to reach and endpoint that prints request.user.is_authenticatedi get False, and request.user returns Anonymous, so i'm not logged in anymore. How can i solve this?
Here is my Axios code:
bodyFormData.append('login', 'root');
bodyFormData.append('password', 'test');
axios({
method: "post",
url: "http://127.0.0.1:8000/accounts/login/",
data: bodyFormData,
withCredentials: true,
headers: { "Content-Type": "application/json" },
})
.then(function (response) {
//handle success
console.log(response);
})
.catch(function (response) {
//handle error
console.log(response);
});
I think Django-Allauth supports AJAX authentication on its urls, but i don't understand how to make it return something and how can my Vue app stay authenticated once i submit the Axios form. Any advice is welcome!

How do I verify the ID token with Firebase and Django Rest?

I just can't wrap my head around how the authentication is done if I use Firebase auth and I wish to connect it to my django rest backend.
I use the getIdTokenResult provided by firebase as such:
async login() {
this.error = null;
try {
const response = await firebase.auth().signInWithEmailAndPassword(this.email, this.password);
const token = await response.user.getIdTokenResult();
/*
No idea if this part below is correct
Should I create a custom django view for this part?
*/
fetch("/account/firebase/", {
method: "POST",
headers: {
"Content-Type": "application/json",
"HTTP_AUTHORIZATION": token.token,
},
body: JSON.stringify({ username: this.email, password: this.password }),
}).then((response) => response.json().then((data) => console.log(data)));
} catch (error) {
this.error = error;
}
},
The only thing I find in the firebase docs is this lackluster two line snippet: https://firebase.google.com/docs/auth/admin/verify-id-tokens#web
where they write
decoded_token = auth.verify_id_token(id_token)
uid = decoded_token['uid']
# wtf, where does this go?
# what do I do with this? Do I put it in a django View?
I found a guide here that connects django rest to firebase: https://www.oscaralsing.com/firebase-authentication-in-django/
But I still don't understand how its all tied together. When am I supposed to call this FirebaseAuthentication. Whenever I try to call the login function I just get a 403 CSRF verification failed. Request aborted.
This whole FirebaseAuthentication class provided by the guide I linked to above - should I add that as a path on the backend?
path("firebase/", FirebaseAuthentication, name="api-firebase"),
Which is the api endpoint my frontend calls?

CSRF_Token in POST method using Vue.js and Django Rest Framework

I'm trying to send a POST request from a Vue.js template to my API created with Django.
When sending I get a 403 CSRF token missing or incorrect error. Since I separated the front and the back, I don't have a view with {csrf_token} on the Django side.
How do I send my form?
I tried some exemples on the web using cookies but i'm beginners and need more explaination about the POST subject and CSRF
I have a Djano View (and urls associated) juste like this :
def get_csrf_token(request):
token = get_token(request)
return JsonResponse({'token': token})
Whe i'm requesting the url, obtained the JSON with the token.
And on the Front side i'm using this method to get the Token :
getToken: function() {
this.loading = true;
this.$http.get('/qualite/get-token/')
.then((response) => {
this.token =response.data;
this.loading = false;
})
.catch((err) => {
this.loading = false;
console.log(err);
})
},
addNc: function() {
let headers = {
'Content-Type': 'application/json;charset=utf-8'
};
if(this.token !== '') {
headers['HTTP_X-XSRF-TOKEN'] = this.token
}
this.loading = true;
this.$http.post('/qualite/api/nc/',this.newNc, {headers: headers})
.then((response) => {
this.loading = false;
})
.catch((err) => {
this.loading = false;
console.log(err)
})
},
For the CSRF you get by default after user login aside with the session, if you're using SessionAuthentication (It's the default authentication used in DRF).
You have to send it with each request in the header, you can refer the this link to know more about the header sent, as it's name is changed and can be configured.
Note also that in the settings you have to make sure that CSRF_COOKIE_HTTPONLY is set to False (which is the default), to be able to read it from the client side JS.
Another path would be removing CSRF enforcement per requests (But it's highly not recommended for security concerns), you can find more about this in the answer here.
Use a Token-based authentification.
Same issue i was encountered with,
the problem was, i had used Class based view and at the time of registered the url i forget to mention as_view() with class Name.
ex:- class PostData(APIView)
before :- path('post_data', PostData)
after correction:- path('post_data', PostData.as_view())