Django doesn't receive cookies from request - javascript

I'm working on a Nuxt/Vue app that uses Django on the backend. I'm using the standard Django Session authentication. The problem with my code is that the user's are always logged out, according to Django, because Django doesn't see any cookie in the request.
Basically i created an API endpoin that should return whether or not the user is authenticated, but since Django doesn't see any sessionid cookie in the request, the user will always be unauthenticated to the backend.
def checkAuth(request):
print(request.COOKIES)
response = {'state': str(request.user.is_authenticated), 'username': str(request.user)}
return JsonResponse(response, safe=False)
If i print request.COOKIES it returns {}.
Here is how i send the request from the frontend, where i'm using Axios:
return axios({
method: 'get',
url: 'http://127.0.0.1:8000/checkAuth',
withCredentials: true,
}).then(function (response) {
console.log(response)
}).catch(function (error) {
console.log(error)
});
The problem should not be from the frontend, since on Chrome i can see the session cookie and the csrf cookie correctly. I already tried to disable any possible CORS security setting on Django. The frontend is running on 127.0.0.1:3000 and the Django app on 127.0.0.1:8000.
Why doesn't Django see the cookies? Any kind of advice is appreciated

Related

How to add protected route in Next.js using jwt token received from custom backend?

I am building a full-stack app with NestJS for the backend and Next.js for the frontend. I have added stateless authentication in NestJS using jwt and passport. Now, I want to add protected route in my Next.js app based on the authenticity of the jwt token that I received from my NestJS backend. What is the best way to achieve this? I want to add protected route for both server-side rendered and client-side rendered pages.
The term 'protected route' refers to being authorized to access certain resources from certain routes (or GraphQL resolvers), so these routes on the server (NestJS) need to check whether the JWT-token is valid and return an appropriate HTTP response. NestJS has built in Guards for that purpose, which return an 401-Unauthorized response in case the JWT is invalid.
So for client-side rendering, if you fetch these resources on your NextJS front-end and include the JWT in the request headers like this: Authorization: Bearer [token], you will know from the HTTP response whether the fetch was successful or not, which will let you either display the data or an error on the front-end.
A simple example for server-side rendering with getServerSideProps could worklike this:
After you Signin via your NestJS server, you set the JWT in a cookie which will be included in every request you make to your NextJS server (its a different server than your NestJS server if you host your NextJS app on vercel)
In getServerSideProps you parse the cookie (on the NextJS server) and add the parsed token to the headers of the request to your NestJS route.
const Component = ({data, authorized}) => {
return {authorized ? <div>Page Content</div> : <div>Log In to view this content</div>}
}
// this function gets called on the NextJS server whenever you visit a page.
// If you're logged in and have a cookie, the cookie will be inside context.req.headers.cookie
export async function getServerSideProps(context) {
// assuming you use the 'cookie' npm package
// and you did not sign the cookie on NestJS with a secret so it has a raw value
const cookies = cookie.parse(context.req.headers.cookie)
const token = cookies.token // assuming you named the cookie 'token' when you set it on your NestJS server
// assuming you use the 'axios' npm package
const response = await axios.get("NestJsServerUrl/route",
headers: {
'Authorization': `Bearer ${token}`
} )
const authorized = response.status != 401
return {
props: {
data: response.data
authorized
}
}
}
Now if you're signed in and you have a cookie with the name 'token' containing a valid token in your browser, your browser will first make a request to the NextJS server with that cookie. This cookie will be extracted and parsed in getServerSideProps on the NextJS server, and will then be used to fetch the resources on the NestJS server by adding it to the Authorization header. Based on the response, the NextJS server will render the page by using conditional rendering.
Let me know if it works.

async req to load/render new page

Im working on a project, using firebase auth for login i.e. login with google; if logged in then redirect to /app where real functionalities of webapp exists.
login page js:
document.getElementById('login').addEventListener('click', e => {
var provider = new firebase.auth.GoogleAuthProvider();
firebase.auth()
.signInWithPopup(provider)
.then((result) => {
firebase.auth().currentUser.getIdToken(true).then(function(token) {
// make request to backend to get /app page where main app exists
axios.get('/app', {
headers: { 'Authorization': `Bearer ${token}` }
})
.then(res => {
console.log(res.data);
});
});
});
});
now my main motive is, user can't access pages other than / (landing page) without JWT token in header.
so here when user log in using login With google it will give token when logged in and then it will make req to backend with token and backend will return /app page pre-rendered!
PROBLEM: using this is code, when i make req to backend it just return HTML code in res.data BUT i want actual page!!
Axios is well and good to fetch data from my backend api but i cant figure out how to attach header and make req, And get page instead of source code in response;
Same problem is occurring everywhere in application. I just don't want users to access pages other than landing page without JWT in header!
backend: nodeJs
firebase auth
ejs template engine for view
EDIT:
meaning of returning source code is:
img of console log
any help, ideas or approach are welcome 🙏🏻
Login as before
Write the token into a cookie instead of the Authorization header
Redirect the browser to /app
In the backend read the cookie instead of the Authorization header
This way the browser will solve the problem for you by rendering the response. Using cookies is the usual way to implement a login without AJAX.
It's not possible to make a redirect and set the Authorization header.

How to stop React-Native-Windows from asking for HTTP Basic Auth credentials

I'm using React Native with the plugin for the Universal Windows Platform to access remote resources on a REST server.
When doing a fetch request for a resource that requires authorization via HTTP Basic Auth, I can provide the request with an additional "Authorization" header and everything works fine as long as the credentials are correct.
If the credentials are wrong I'm presented with a Windows-native login prompt (similar to the one when connecting to a remote computer). This prompt is not managed by my app, but automatically seems to pop up when the underlying network connection detects a 401 Unauthorized server response.
Here is what I do inside React Native:
let encodedCredentials = new Buffer(this.state.username + ":" + this.state.password).toString("base64");
let response = await fetch(this.state.serverUrl, {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': "Basic " + encodedCredentials,
}
});
let responseJson = await response.text();
alert(responseJson);
The server response, when provided with incorrect credentials, includes:
Status Code: 401 Unauthorized
WWW-Authenticate: Basic realm="iOSResource"
Note that the native login prompt seems to delay the fetch request as a whole. I can enter wrong credentials and confirm the prompt multiple times without the alert firing once. Only when the prompt is explicitly cancelled, the correct credentials are entered or wrong credentials have been tried a couple of times the fetch await continues.
Unfortunately this brings up another issue: When entering wrong credentials in the popup prompt a couple of times and it finally "gives up", I can supply whatever credentials I want to the fetch request, it will not supply my own authorization header to the server in any future requests. The data sent will be stuck to whatever I entered in the prompt before it closed. In this case it does not bring up the prompt again and the request just immediately fails. That leaves me unable to correct the credentials in my own app, because they are simply not sent within the request. I have confirmed this by inspecting the outgoing data in Wireshark.
I guess Windows seems to transparently tamper with the network request to intercept special response codes and re-prompt credentials if necessary before returning the request result to the actual caller for the first time.
I want to deal with incorrect credentials in the app, instead of causing Windows to intercept requests. Is there a way to suppress this native prompt and immediately proceed with my own code in case the Basic Auth fails?
Edit: The behavior is exactly the same when using Axios instead of plain fetch. Seems like both ultimately do a XMLHttpRequest, which is filtered the same way.

JWT token with AJAX, non-AJAX, JQuery

I'm a bit frustrated with managing my JWT token during login, submits and redirects. Before I get started here's my technology stack just in case:
JQuery/Html -> Node.Js -> Java Restful Services -> MySQL.
My java Restful services manages creating the JWT Token returning it to the Node.js layer which decides what to do with it and pass it on the the client. This all works wonderfully.
To get the JWT token I'm making an ajax based authentication request to the Node middle tier, which authenticates and returns the token which is summarily crammed into localstorage on the client.
Now I have no desire what so ever to make the entire site load off a single page through ajax, it's a complex site and doing that is just dumb! I need to forward and navigate to sub pages while carrying along the JWT token.
Here's the question (finally)... How do send along the JWT token to the middle tier (node.js) without attaching it as a request or post parameter because that's a big no no? I can't seem to find a way to stuff it in the header associated with Bearer.
You need to store the token at client side using for example a cookie or localStorage
Ajax requests
Cookies: A cookie is sent automatically when making a request to the server, so you do not need to add a specific header
LocalStorage:It is needed to provide the token in each request using an HTTP header.
For example
POST /authenticatedService
Host: example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
This is an example code to show how to execute an ajax POST request using jquery
$.ajax({
type: "POST", //GET, POST, PUT
url: '/authenticatedService' //the url to call
data: yourData, //Data sent to server
contentType: contentType,
beforeSend: function (xhr) { //Include the bearer token in header
xhr.setRequestHeader("Authorization", 'Bearer '+ jwt);
}
}).done(function (response) {
//Response ok. process reuslt
}).fail(function (err) {
//Error during request
});
Form submit
With a form submission you can not control the headers set by browser, so it is not possible to set the Authorization header with a Bearer token. In this case you can
Cookie: store the JWT in a cookie that will be sent with the form data. You will need to add extra security to avoid CSRF attachs
Form param: The JWT is stored in a hidden field of the form.
Use always POST (not GET) to avoid cache of JWT
Link
A link executes a GET request. You could build the link adding the JWT as a query param url?jwt=...
But, consider in this case the security risks. Browser can cache the url and it will be present in logs. An attacker could potentially obtain them if he has access. Also the user could copy the link and use it outside your web application (e.g send it by email...)
If you use cookies, the token will be automatically sent to the server by clicking on the link, but this will only work if the user is authenticated. In this case be aware of CSRF vulnerabilities
Your only option is to store the token in a cookie if you don't want to do anything suggested above. You can't set http headers in links.

Login and logout in Node.js using authentication token

I'm working in Node.js Application. it requires login, logout ,and sign up functionalities I was thinking in creating the authentication using token based instead of cookies. and this will be the workflow
Send POST /login to the server to check if the user exist or not
if user exist I will send the token in JSON object and store it in the browser local storage
Now I want to redirect to home page after storing the token using window.location = "/"but I need to insert the token in the header and this my problem I found that's possible in angular using $httpProvider.interceptors that will intercept every request and set its header.
Is there any way that I can do that without angular?
This is normally good concept when using an API and then a web app in front of it.
Basically you have to save your token and send it with every request, if you have it.
What I normally do is when I do the /login I store the token in the localStorage of the browser, you can use this library to use it https://github.com/julien-maurel/jQuery-Storage-API
Once you have the token in your localStorage, when you do a call to the API you check if there's the token in the localStorage, if there's add a header.
Here's an example using jQuery ajax:
$.ajax({
url: '/data',
headers: {
'Authorization':'Bearer ' + localStorage.get('token')
},
method: 'POST',
dataType: 'json',
data: {},
success: function(data){
console.log('succes: '+data);
}
});

Categories

Resources