I'am using django and trying to destroy a token when user log out, this is the function I'am using :
const logMeOut = async () => {
setAnchorEl(null);
const response = await fetch('http://127.0.0.1:8000/api-auth/token/logout/', {
method: 'POST',
headers: {
'Authorization': 'Token '.concat(GlobalState.userToken),
'Content-Type': 'application/json',
},
})};
However my server is throwing :
POST http://127.0.0.1:8000/api-auth/token/logout/ 401 (Unauthorized)
What I'am I doing wrong ? I know it's something about the headers or something like that... but I have been switching headers and nothing changes.
Okay, I found out what the problem was and I'll leave it here for anyone who might be facing the same issue.
In my particular case, I was getting unauthorized because I send the same token multiple times and the token was destroyed the first time I sent the request to the backend...
Basically, I didn't destroy the token in the frontend and kept sending the same token which was already destroyed, which means there is nothing wrong with the piece of code above and it should work.
Related
I'm new to using the rest-client. I know I'm missing something, but I am trying to do the following:
Post to a login endpoint to authenticate
After authentication, post csv text to another endpoint that requires a logged in user
The authentication portion is successful, however, I am getting a 401 Unauthorized when step 2 occurs.
rest_client = RestClient
login_response = #global_rest_client.post(
host + 'LOGIN ENDPOINT',
{ userName: 'user', password: 'password'},
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
)
import_response = rest_client.post(
host + 'IMPORT DATA ENDPOINT',
headers: { 'X-System-Name': 'AndroidMobile', 'Content-Type': 'multipart/form-data },
csv: csv_string
)
My understanding of how authentication works could be wrong. My assumption is that as long as the same instance of the client has a successful login, then the post of csv data would also be successful.
I appreciate any input.
HTTP (1.1) is stateless so a request does not contain any information about previous requests unless that information is encoded and added to the request in some way (e.g. cookies or headers). So when you make your import request the server does not know if/that you are authenticated even though you just made a login request.
You'll have to include the token you receive from your login request in subsequent requests. This should go in the 'Authorization' header.
For example:
auth_token = login_response["success"]["token"] # or whatever the key is for the token
import_response = rest_client.post(
host + 'IMPORT DATA ENDPOINT',
headers: { 'Authorization': "Bearer #{auth_token}", 'X-System-Name': 'AndroidMobile', 'Content-Type': 'multipart/form-data },
csv: csv_string
)
The way authentication works depends on the server and can be different in different cases. So the site you are accessing might expect the Authorization header to be like "Token #{auth_token}" or anything else, but they should mention it in their documentation.
I use Vuejs to create my frontend for my project.
At the creation of one component ('TimeCapsy.vue'), I make an AJAX call to my backend like this:
created: function () {
if (verify.verify_login()) {
let token = this.$cookies.get('jwt_us_cas');
let params = {'jwt': token};
console.log(params);
axios({
method: 'post',
url: dev.HOST+'getuserinfoobject',
params: queryString.stringify(params)
})
.then(response => {
console.log(response.data)
})
}
}
As you can see I use the
this.$cookies.get('jwt_us_cas');
to get the a json web token, that I set on the client at the login.
I use the queryString Library to stringify my parameters for my request.
I also tried it without the queryString.stringify(params) call, but I get the same error, e.g. the parameter still turns into null.
When I look at the console log, where I check the params variable, I get this output:
{jwt: "my token comes here"}
So I can see, that it gets the correct value from the cookie.
But when I check the answer from my backend (PHP), I get this error:
Undefined index: jwt in <b>D:\casb\public\index.php</b> on line <b>52</b>
Of course I know that it means, that jwt is null, but I can't understand why.
As I said, right before I make the call I check the params and it shows the token.
I checked the endpoint with Postman and the token as the jwt parameter and it returned a successfull call with the correct answer.
A correct answer is basically just a nested object with some information in it.
My PHP endpoint is pretty basic too:
Router::add('/getuserinfoobject', function () {
$response['response'] = User::getUserInfoObject($_POST['jwt']);
echo json_encode($response);
}, 'post');
So I guess that right before or in my call it nulls my parameter. But I can't understand how, since I make a lot of requests and never had this problem.
From axios docs
params are the URL parameters to be sent with the request
Which means, you should get the value with PHP $_GET.
Or $_REQUEST (which stores both $_GET, $_POST. Also $_COOKIE).
The other hand, you can use data key as docs says
data is the data to be sent as the request body
Only applicable for request methods PUT, POST, and PATCH
So the value would be available in $_POST
axios({
method: 'post',
url: dev.HOST+'getuserinfoobject',
data: {
jwt: token
}
})
I've got a problem and I have no idea why it appears. The circumstances of its appearance are very strange for me...
I've got a POST REST service /login. It expects json {"email":email,"password":password}. I am using ajax and everything works correctly... except for the case when email (is in real format) contains '#' sign and some letters before and after( I know it is strange but only in this case such error appears). When I pass email i.e "mum#mum.com" then few things are happening:
I see that browser sends GET request instead of POST and obtains 304 http status
In the browser console I see infomation "The development server has disconnected. Refresh the page if necessary" and page refreshes automatically
The above things happen only when email is in format I described above.When I pass "aaa" or "aaa#" as email everything works correctly(browser sends POST request and I don't get error in console).
I honestly have no idea why this happens... would be extremely grateful for your help and I will answer all your questions concerning this.
PS.
When I use REST web service tool in IntellJ everything always works fine.
handleLogin() {
const input = {
email: this.state.email,
password: this.state.password
};
$.ajax({
url: CONST.USER_SERVICE + "/login",
type: "POST",
data: JSON.stringify(input),
contentType: "jsonp"
})
.fail(function () {
alert("Wrong data");
})
.always(function (arg1, arg2, arg3) {
if (arg3.status === 200) {
alert("ok!");
}
}.bind(this));
}
Try making the ajax request like data: input without stringify. Ajax expects an object.
I'm making a client-side request out to V2 of the Square API using Vue and Axios. My Vue component is as follows:
import axios from 'axios';
export default {
mounted() {
var instance = axios.create({
baseURL: 'https://connect.squareup.com/v2/',
timeout: 1000,
headers: {
'Authorization': 'Bearer xxxxxxxxxxxxxxxxx',
'Accepts': 'application/json',
'Content-Type': 'application/json'
}
});
instance.get('catalog/list')
.then(function (response) {
console.log(response);
}) ;
}
}
However, when I make that call, I receive the following error:
Failed to load https://connect.squareup.com/v2/catalog/list: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://local-env.dev' is therefore not allowed access. The response had HTTP status code 403.
That error suggests that there is some configuration that has to happen on the Square side, but I saw no opportunity to whitelist domains, etc.
Has anyone come across this error before, regardless of service, and if so, how did you resolve?
I don't think the Square API supports being called from a browser. I used Postman to do an OPTIONS request on https://connect.squareup.com/v2/catalog/list and the response was a NOT_FOUND. The OPTIONS request is needed for proper CORS support.
Plus, if you did this, I would think your auth token would need to be sent to the client -- thus exposing it to everyone. It looks like the Square API is only designed to be called from a server. But that is just based on me skimming the docs a bit. I have no experience using their API.
When doing OAuth authorization request you are not supposed to do it from your application. Create and URL with the parameters and open it in a new browser window or tab, Something like:
const grants='MERCHANT_PROFILE_READ CUSTOMERS_READ CUSTOMERS_WRITE PAYMENTS_READ PAYMENTS_WRITE PAYMENTS_WRITE_ADDITIONAL_RECIPIENTS PAYMENTS_WRITE_IN_PERSON';
const params = new HttpParams()
.set('scope', grants)
.set('client_id', <YourSquareApplicationId>)
.set('state', '1878789');
const requestUrl = `${<squareUrl>}/oauth2/authorize?${params.toString()}`;
window.open(requestUrl, "_blank");
That new window is supposed to ask the end user to login to his account and accept or deny the request.
I'm developing a django system and I need to create a chat service that was in real-time. For that I used node.js and socket.io.
In order to get some information from django to node I made some ajax calls that worked very nice when every address was localhost, but now that I have deployed the system to webfaction I started to get some errors.
The djando server is on a url like this: example.com and the node server is on chat.example.com. When I make a ajax get call to django I get this error on the browser:
XMLHttpRequest cannot load http://chat.example.com/socket.io/?EIO=3&transport=polling&t=1419374305014-4. Origin http://example.com is not allowed by Access-Control-Allow-Origin.
Probably I misunderstood some concept but I'm having a hard time figuring out which one.
The snippet where I think the problem is, is this one:
socket.on('id_change', function(eu){
sessionid = data['sessionid']
var options = {
host: 'http://www.example.com',
path: '/get_username/',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': sessionid.length
}
}
var request = http.request(options, function(response) {
response.on('data', function(msg){
console.log('Received something')
if(response.statusCode == 200){
//do something here
}
}
})
})
request.write(sessionid);
request.end();
});
And I managed to serve socket.io.js and make connections to the node server, so this part of the setup is ok.
Thank you very much!
You're bumping into the cross origin resource sharing problem. See this post for more information: How does Access-Control-Allow-Origin header work?
I am NOT a Django coder at all, but from this reference page (https://docs.djangoproject.com/en/1.7/ref/request-response/#setting-header-fields) it looks like you need to do something like this in the appropriate place where you generate responses:
response = HttpResponse()
response['Access-Control-Allow-Origin'] = 'http://chat.example.com'