csrf validation failed when I login - javascript

I have a view in my django backend called getUserInfo that will return the user's info as json format.
This is my view:
#api_view(["POST"])
def getUserInfo(request):
if request.user.username:
serial = userInfoSerializer(request.user)
return Response(serial.data)
else:
return Response({"notLoggedIn": True})
When I'm not logged in ajax request are working ok but when I login to a user account I get an "forbidden" error and it says csrf validation failed. I am also refreshing the csrf token every time the user logs in or out.
So it should work but it is not working.
This is my ajax request:
function login(){
getcsrf();
$.ajax({
url: '/api/login/',
type: 'POST',
headers: {
"XCSRF_TOKEN": csrf
},
data: {
username: $("#l-username").val(),
password: $("#l-password").val(),
},
})
.done(function(data) {
console.log(data)
if(data.msg){
console.log(data.msg)
$(`<div class="p-2 bg-danger">`+data.msg+`</div>`).prependTo('#message-box')
}else{
getcsrf();
getUserInfo();
}
console.log("success");
})
.fail(function() {
console.log("error");
})
.always(function() {
console.log("complete");
});
}
The function getcsrf refreshes the global variable containing the csrf-token value called "csrf" and then I send my ajax request. After the request I refresh it again. I'm sure the value of csrf token changes every time I am refreshing it when user logs in or out but server always says "forbidden".
I have inserted this code in my settings.py file:
CSRF_HEADER_NAME = "HTTP_XCSRF_TOKEN"
and I am sending ajax request with a header called XCSRF_TOKEN
Can any one help me?
SORRY FOR MY ENGLISH

Maybe try:
headers: {
"HTTP_XCSRF_TOKEN": csrf
},
so that it matches the header name in your settings file.

okay let me answer it my self.
i cleared my browser cookies and then it worked properly

Related

Can't login after logout Laravel

I have developed a dynamic page with javascript (no reloading) where a user inserts a private number.Then I send a Ajax request to manually log in the user associated with that number.After that if the user wants he can exit (send Ajax request to logout) and the main page appears to log in again.
Steps To Reproduce:
Enter Number, click login and I verify that the first login works.
Click exit and the logout works
Insert same or another number and click login again and now the user is not authenticated.
Note: If I refresh the page after exit(logging out), the 2nd login works.
-> Code where I send Ajax request to verifyNIF()
$('#start').on('click', function() {
$.ajax({
url: '/' + slug + '/vote-in-person/verify-nif',
type: "POST",
data: {
nif: nif
},
dataType: "json",
success: function (data) {
//NIF VERIFIED AND USER LOGGED IN
}
});
});
-> verifyNIF() verifies the number on the DB and then authenticates the user
Auth::login($user);
-> logout() function, which uses Laravel Fortify logout route.
function logout(){
$.ajax({
url: '/logout',
type: "POST",
success: function () {
console.log("logged out");
// location.reload();
},
error: function (data) {
console.log(data);
}
})
}
On the front side, the CSRF token becomes invalid after logout with an ajax request. You can add a new endpoint to refresh the CSRF token manually. I think that helps you. https://stackoverflow.com/a/57252273/9215587

Make post request from js to django rest framework

I have a DFR api endpoint:
url = http://127.0.0.1:8000/x/y/
Url of the page running JS code: http://127.0.0.1:8000/x/z/1/
I have logged in as User1 in my browser.
POST request - from DRF browser api - good.
GET request - from javascript - good.
POST request - from javascript - 403 error.
So perhaps I dont know how to make an authenticated ajax request from JS. When I do the same request from browser api, may be the browser takes care of authentication.
My current js code:
axios({
method: 'post',
baseURL: window.location.origin,
url: '/x/y/',
// adding auth header also gives same 403 error for post request
// headers: {
// Authorization: 'Token e77b8ca898b51cde72dcf2aa2c385942d771e972'
// },
data: {
name: 'xyz'
},
responseType: 'json',
})
.then(function (response) {
console.log(' success');
})
.catch(function (error) {
console.log(' error=', error.message);
});
If you are on chrome browser, go in console ctrl+shift+j and then go in network.
When a post request is made, we can see the error message in this network tab.
My post request had following error:
"CSRF Failed: CSRF token missing or incorrect."
To add csrf token on axios ajax request put following lines of code at beginning of your js file:
axios.defaults.xsrfCookieName = 'csrftoken';
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN";
Are you appending the CSRF token in your request,CSRF can cause 403 errors.Try appending csrf token in request headers

AWS API Call with Authorization Header ( session.getIdToken().getJwtToken() )

I Have a WebPage That USE AWS API Gateway using AWS-Cognito Authentication. Most of the Buttons in Web Page Call Api and send or Retrieve data. This is the Code I Use Under Every Button Click
getAuthenticateUser().getSession(function(err,session){
if (err) {
console.log("Error"+err);
return;
}
if(session.isValid())
{
$.ajax({
url: URL,
headers:
{
'Authorization':session.getIdToken().getJwtToken(),
'Content-Type':'application/json'
},
method: 'GET',
dataType: 'json',
success: function(data){
// Execute Function Need to Execute on Success
}
,
error: function (xhr, textStatus, errorThrown) {
console.log(errorThrown);
}
});
}
if(!session.isValid())
{
console.log("Session is not valid..!");
//Please Login to Continue
}
});
This is Working Fine without Issue.But the Problem is It take Some Time to Execute it Everytime and Feeles like every time it Gives a New Session for Each call even Previous Session is not Expired. How can I Use get new Session Only when it Expired and if Previous Session is not Expired just check the validity of it globally and get a new Authorization Header Only I need..?
Because In My Code Once User Press One Button and Send Data id same User press another button after 30 sec i'm getting new session again right ..? it really gives me really bad on web site Performance.
Any Idea How to Solve this ..?
this my getAuthenticationUser() Code
function getAuthenticateUser()
{
return userPool.getCurrentUser();
}
and this my Global Variable in that Javascript page
var poolData = {
UserPoolId : 'usXXXXXXXXXXOv3jSL',
ClientId : 'XXXXXXXXXXka8g'
};
var userPool = new AWSCognito.CognitoIdentityServiceProvider.CognitoUserPool(poolData);
getSession() does not create a new session if the current session is valid.
If the current session is either null or invalid, it tries to refresh the session (using the refresh token) to get the ID token that is necessary to successfully complete the HTTP request using the Authorization header. Otherwise, it throws an error requesting to authenticate.
You can see what getSession() exactly does by taking a look at the CognitoUser class definition. (currently on line 1016.)

Simple JWT Auth using Jquery

I am trying to do a simple JWT Authentication using only JQuery. I have already tested the backend with postman and everything seems to work in there.
Here's how my frontend code looks like
$("#send").click(function(){
var name = $('#name').val();
var password = $('#password').val();
var token = ''
$.ajax({
type: 'POST',
url: '/authenticate',
data: { name: name , password: password },
success: function(resultData){
var token = resultData.token;
// console.log(token);
$.ajax({
type: 'GET',
url: '/memberinfo',
headers: {"Authorization": token},
success: function(data){
$(location).attr('href', '/memberinfo')
}
});
}
});
});
so when I get redirected to the memberinfo page it shows me I am unauthorised. Not quite sure if I am doing the Ajax calls properly. Would be really helpful if some one could direct me the right way. Thanks
For simple use case just retrieve a token in the login request response and save it to the localStorage or sessionStorage. Then use the token from the localStorage inside every request header.
Please, have a look at an example code here.
https://github.com/chaofz/jquery-jwt-auth
On the other hand that is not secure to store a token in these storages as it is not protected from XSS attacks.
You better store token in cookies and check your cookies policies to prevent CSRF attack.
Please read more here
i may be wrong, but a quick look of your code it might be because you set the api call for GET request and your client page the same url /memberinfo. your test result using Postman is working and also you are properly redirected to the /memberinfo upon success validation, however, since you are redirected to the same /memberinfo url and your browser didn't send headers: {"Authorization": token} you received unauthorised result.
try to make the api call url different with the client member page.
You need to add word "Bearer":
headers: {"Authorization": "Bearer " + token}, // note the space after Bearer

AJAX call in Scala Play: Data not transfered

I'm about to implement a Login using Google OAuth. I followed the official Google docs
The client does get a token from the Google server. But whenever I try to send it back to my server to store it, I do not seem to get data from the AJAX call. Here is my code:
function signInCallback(authResult) { //called when client has confirmed the Login dialog
if (authResult['code']) {
// Hide the sign-in button now that the user is authorized, for example:
$('#signinButton').attr('style', 'display: none');
console.log("signinCallback. Send code to server:")
console.log("Code = "+ authResult['code']);
console.log("performing AJAX call now...\n\n")
// Send the code to the server
$.ajax({
type: 'POST',
url: 'http://localhost:9000/storeauthcode',
contentType: 'application/octet-stream; charset=utf-8',
success: function(result) {
// Handle or verify the server response.
console.log("AJAX call --> success");
console.log(result)
},
processData: false,
data: authResult['code']
});
} else {
//There was an error.
console.log("AJAX call failed.")
}
I created a line in my routes file:
POST /storeauthcode controllers.Application.storeAuthCode
The method on the server:
def storeAuthCode = Action { request =>
Ok("storeauthcode called with queryString = "+request.rawQueryString)
}
The following is a console output of my Chrome browser:
hello.js:2 Welcome to your Play application's JavaScript!
(index):67 signinCallback. Send code to server:
(index):68 Code = <token deleted for privacy reasons>
(index):69 performing AJAX call now...
(index):77 AJAX call --> success
(index):78 storeauthcode called with queryString =
So although my browser gets a token back, I cannot store it on the server, because I don't get any data back.
Ok("storeauthcode called with queryString = "+request.body.asJson)
is also empty.
This one here also delivers an empty result:
def storeAuthCode = Action { request =>
Ok("storeauthcode called with queryString = "+request.getQueryString("data"))
}

Categories

Resources