I am using Axios to Signup to our server. Which is returning fine now. However, I do not know how to retrieve the access token from a separate url.
The signup request looks like this:
let settings = {
url: "https://api.dev.etcetc.com/user/signup",
data: {
Username : username,
Password : password },
method: 'POST',
headers : {
"Content-Type" : "application/json"
},
transformRequest: [(data) => {
return JSON.stringify(data);
}]
};
The access token is to be retrieved from a url like:
https://api.dev.etcetc.com/token
Do I run another Axios request( this time GET instead of POST)? I have not been given any info on how to or whether to provide any config for this access token call.
maybe the url will give you a code, you can use the code to get the token in you java or php code with the apt which Axios provide
Related
Making a post request via insomnia/postman works, gives me the correct response. However, in axios, I can't seem to make it work.
It doesn't give me an error, its a status 200, but doesn't actually login like postman/insomnia does. I feel something is wrong with my axios setup
const { email, password } = req.body.params
const endpoint = `https://xxxxxxxxx.com/account/login/`
try {
const response = await axios({
method: 'post',
url: endpoint,
data: qs.stringify({
'customer[email]': email,
'customer[password]': password,
'form_type': 'customer_login'
}),
headers: {
'content-type': 'application/x-www-form-urlencoded'
}
})
res.status(200).send(response.data)
} catch (error) {
res.status(500).send(error)
}
There are 2 solutions (I hope) :
1/ Following this post, you should probably use withCredentials like this :
const { email, password } = req.body.params
const endpoint = `https://xxxxxxxxx.com/account/login/`
axios.defaults.withCredentials = true;
try {
(...)
}
2/ Following this article, you need to set your Content-Type header to application/json so the data is automatically parsed :
Axios also sets the Content-Type header to application/json. This enables web frameworks to automatically parse the data.
Postman lets you generate the code necessary to recreate your request using axios.
More information on that here: https://learning.postman.com/docs/sending-requests/generate-code-snippets/
Click the code icon to the right of Postman
Then set the code snippet language to NodeJS - Axios and you'll have the exact code necessary to recreate the request.
I am trying to create API request for login to chess.com site, but it looks like the request fails. Steps to reproduce:
I send the request manually and check it in Google developer tools. Here is the result:
Request URL: https://www.chess.com/login_check
Request Method: POST
Form Data
_username: user#test.com
_password:1234567
login:
_target_path: https://www.chess.com/
_token: cQr-epETT8R1cTUDY-AFua1cHdE46sHqY3OyDXgDz_k
I created GET request in Cypress for getting the token and then used this token along with my credentials in my POST request to the server to be logged in. Here is my request:
describe("Login via API", () => {
it("Send request for the token", () => {
cy.request("GET", basicLinks.loginUrl).then((response) => {
const token = Cypress.$(response.body).find("#_token").attr("value");
cy.request({
method: "POST",
url: "/login_check",
form: true,
body: {
_username: "test#yahoo.com",
_password: "12345",
login: {
_target_path: "https://www.chess.com/",
_token: token,
},
},
});
});
});
});
But it look that there is something wrong with the request because as far as I can see I got the initial login page as the server response. Could anybody advise what I am doing wrong and how can I fix my request? Please find attached screenshot containing the data mentioned above.
I have a Django web app that is using the Django REST framework to generate various API endpoints.
I can ensure only logged in users can view/read these endpoints, but now I am at the stage of development where I want users to post to the API using tokens. I have successfully done this, however, I have hard-coded the users token into the post request in Javascript... This worked for testing but obviously is not a good final solution.
Is it possible to request the current users token somehow? Could I then include this token in the POST request head automatically?
Thanks for any help/feedback in advance!!
EDIT:
I think I am close, but I am getting a few errors in my chrome console, and still can't retrieve token.
Console Errors:
toggleScript.js:25 Uncaught DOMException: Failed to execute
'setRequestHeader' on 'XMLHttpRequest': The object's state must be OPENED.
at getToken (http://127.0.0.1:8000/static/defaults/toggleScript.js:25:7)
at manageDefaults
(http://127.0.0.1:8000/static/defaults/toggleScript.js:62:5)
at HTMLInputElement.onclick (http://127.0.0.1:8000/defaults/:1:1)
getToken # toggleScript.js:25
manageDefaults # toggleScript.js:62
onclick # (index):1
toggleScript.js:24 POST http://127.0.0.1:8000/api-token-auth/ 415
(Unsupported Media Type)
I have a button when pressed, will trigger the function to retrieve the token, and this is what is causing the error stack above.
toggleScript.js
function getToken(){
var xhr = new XMLHttpRequest();
var url = 'http://127.0.0.1:8000/api-token-auth/';
xhr.open("POST", url, true);
var data = JSON.stringify({"username": "myusername", "password": "mypassword"});
xhr.send(data);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
var json = JSON.parse(xhr.responseText);
console.log(json.token);
}
};
}
Django Rest Framework provides an API endpoint for requesting a user's token, given a username and password. You can wire the view into your urls.py:
from rest_framework.authtoken import views
urlpatterns += [
url(r'^auth-token/', views.obtain_auth_token)
]
Then when you POST a valid username and password to that view it will return the token in a JSON response:
{ 'token' : '9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b' }
Your app can then store that and send it in subsequent requests.
An example of retrieving the token using JQuery (assuming the view was mapped to the path ^auth-token/ in your urls.py):
$.post('/auth-token/', { username: 'admin', password: 'whatever' }, function(data) {
// Token available as data.token
});
If you try and post to the auth-token view from within an already authenticated session, Django will likely reject the request with a CSRF token missing or incorrect response. You should either ensure that the session is not authenticated when you retrieve the token, or you could potentially include the X-CSRFToken header in the request. You'd need to extract the value from the csrftoken cookie. For example (using JQuery and the JQuery Cookie plugin):
$.ajax({
url: "/auth-token/",
type: "POST",
headers: {
"X-CSRFToken": $.cookie("csrftoken") # Extract the csrftoken from the cookie
},
data:{ username: "admin", password: "whatever" },
dataType:"json"
}).done(function(data) {
// Token available as data.token
});
More info on obtaining an auth token here
I'm trying to exchange my Dropbox oauth code for a token as per the http api documentation.
When I perform the command with curl thusly:
curl https://api.dropbox.com/1/oauth2/token \
-d code=<authorization code> \
-d grant_type=authorization_code \
-u <app key>:<app secret>
everything works fine, and I am returned my bearer token. Unfortunately, what
seems to be equivalent code written in node.js with the request module fails.
var request = require("request");
var config = require("./config.json");
request({
url: "https://api.dropboxapi.com/1/oauth2/token",
method: "POST",
auth: {
user: config.client_id,
pass: config.client_secret
},
json: {
code: config.code,
grant_type: "authorization_code"
}
}, function(err, resp, body) {
if (err) throw err;
console.log(body);
});
logs:
{ error_description: 'missing required field "grant_type"',
error: 'invalid_request' }
The docs
say that in the event of a 400 error (which this is), I have:
Bad input parameter. Error message should indicate which one and why.
Though as can be seen from the above code, the grant_type is being
specified.
Notably the docs give a second option to authenticate, though this too fails,
albeit with a different message:
Description (abridged)
Calls to /oauth2/token need to be authenticated using the apps's key and secret. These can either be passed as POST parameters (see parameters below) or via HTTP basic authentication. If basic authentication is used, the app key should be provided as the username, and the app secret should be provided as the password.
Params
code String The code acquired by directing users to /oauth2/authorize?response_type=code.
grant_type String The grant type, which must be authorization_code.
client_id String If credentials are passed in POST parameters, this parameter should be present and should be the app's key (found in the App Console).
client_secret String If credentials are passed in POST parameters, this parameter should be present and should be the app's secret.
redirect_uri String Only used to validate that it matches the original /oauth2/authorize, not used to redirect again.
My attempt at the alternate authentication procedure:
var request = require("request");
var config = require("./config.json");
request({
url: "https://api.dropboxapi.com/1/oauth2/token",
method: "POST",
json: {
code: config.code,
grant_type: "authorization_code",
client_id: config.client_id,
client_secret: config.client_secret
}
}, function(err, resp, body) {
if (err) throw err;
console.log(body);
});
logs:
{ error_description: 'No auth function available for given request',
error: 'invalid_request' }
In case the full response from dropbox for either of my two request attemps would be helpful I posted it on pastebin.
I am not including the redirect_uri as I did not use it as part of the code
flow. This is permitted as per the docs. In any case, I don't have any problems
when ommitting it in the curl command which does succeed.
Considering that my API call succeeds when sent through curl, I'm clearly doing
something wrong with my js request. What can I do to get the bearer token I
expect?
It looks like in your curl command, you're sending a form-encoded POST request (which is what OAuth uses), but in your Node.js code, you're sending a JSON-encoded request.
Try form: { ... } instead of json: { ... }.
My code is attempting to post data to a Coldfusion API from my local Node.js server. I have managed to communicate with the API and authenticate myself via the request headers. However I am having difficulty actually passing my JSON object through as I cannot get the structure right.
The API does not accept the JSON option of the request module, so that is my easiest option out of the window.
The API is expecting the following:
{
'source': {
'customer': {
'customerlogin': 'myusername',
'customerpassword': 'mypassword',
}
}
}
my code works if I hard code the following body parameter (from a sucessful post by somebody else) into my post.
var Jrequest = require('request');
var options = {
uri: 'http://myAPI/customerSSO.json',
headers: {'Content-Type': 'application/x-www-form-urlencoded', 'Authorization': something', 'Timestamp': timestamp},
method: 'POST',
body: 'source=%7B%0D%0A++%22customer%22%3A+%7B%0D%0A++++%22customerlogin%22%3A+%22myusername%22%2C%0D%0A++++%22customerpassword%22%3A+%22mypassword%22%2C%0D%0A%09%22success%22%3A+%22%22%0D%0A++%7D%0D%0A%7D' // Working
};
Jrequest(options, function (error, response, body){
res.send(body);
});
If I send the JSON through in other ways, for example json.stringify(), it is rejected on the grounds that 'source is required but not defined'.
So I suppose my question is, in node.js how do I turn JSON into something that looks like this
'source=%7B%0D%0A++%22customer%22%3A+%7B%0D%0A++++%22customerlogin%22%3A+%22myusername%22%2C%0D%0A++++%22customerpassword%22%3A+%22mypassword%22%2C%0D%0A%09%22success%22%3A+%22%22%0D%0A++%7D%0D%0A%7D'
or have I overlooked another option?
Thanks for any help and apologies if I have used incorrect terminology.
I think this should work:
var querystring = require('querystring');
...
request({
...
headers : { 'Content-Type': 'application/x-www-form-urlencoded', ... },
body : 'source=' + querystring.escape(JSON.stringify({
'customer': {
'customerlogin': 'myusername',
'customerpassword': 'mypassword',
}
})),
...
}, ...)
Your example also contains newlines and carriage returns and such, but I'm assuming those are optional.