Error 405 using axios post request in react native - axios

I'm making an post request using axios in my expo react native app but I don't know why my post request is returning error
Request failed with status code 405
When I check my API on postman so it shows me the expected result. I attached the method which hits onPress on button. Kindly check and provide me a solution.
async onSubmit(ref) {
if (ref.state.emailID && ref.state.password) {
this.showLoader();
await axios.post('http://apiurl.com/api/user/Userlogin?emailID=' + ref.state.emailID + '&password=' + ref.state.password,
{ emailID: ref.state.emailID, password: ref.state.password },
{ headers: { 'Content-Type': 'application/json' } })
.then((response) => {
console.log('Innnn');
this.hideLoader();
console.log("response data: ", response.data);
}).catch(err => {
this.hideLoader();
console.log("error: ", err.message);
})
}
}

Okay, so there are multiple things which are wrong in you code.
To answer your question at start, I would suggest you to add withCredentials: true}
Try adding {withCredentials: true} in your axios request.
Second, with async and await, you don't need to use .then and catch (rather use try..catch)
async onSubmit(ref) {
if (ref.state.emailID && ref.state.password) {
try {
this.showLoader();
const networkReq = await axios.post('http://apiurl.com/api/user/Userlogin?emailID=' + ref.state.emailID + '&password=' + ref.state.password,
{withCredentials: true},
{ emailID: ref.state.emailID, password: ref.state.password },
{ headers: { 'Content-Type': 'application/json' } })
this.hideLoader();
console.log(networkReq.data)
} catch (error) {
this.hideLoader();
console.log("error: ", err.message);
}
}
}

I was doing a very silly mistake, the request has been changed from post to get.

Related

Axios bad request 400 Spotify post

I am getting a bad request of 400 from Axios for trying to get the token from the Spotify API. Can someone please look at my code?. I would really appreciate someone's help.
app.get("/auth/callback", async (req, res) => {
try{
let code = req.query.code || null;
let state = req.query.state || null;
let data = qs.stringify({
grant_type: "authorization_code",
code: code,
redirect_uri: redirect_uri,
});
const response = await axios.post('https://accounts.spotify.com/api/token', data,
{
headers: {
'Authorization': `Basic ${Buffer.from(client_id + ':' + client_secret).toString('base64')}`,
'Content-Type': 'application/x-www-form-urlencoded',
},
})
res.send(response)
}catch(error){
res.send(error)
}
})

axios interceptors how to use them with axios.create()

I have the following code which I import and use in a VueJS application.
I want to be able to errors returned by the API centrally and it seems that interceptors would do the job for me but I don't understand where I set them up
import axios from 'axios'
import store from './store/index'
export default () => {
try{
var token = store.state.user.token.token
}catch(err){
var token = ""
}
return axios.create({
baseURL: "http://localhost:3333/api/v1",
headers: {
"Authorization": `Bearer ${token}`
}
})
}
I have tried this, but it does not work.
import axios from 'axios'
import store from './store/index'
axios.interceptors.request.use((config) => {
console.info("debug ", config);
return config;
}, (error) => {
console.error("debug ", error);
return Promise.reject(error);
});
export default () => {
try{
var token = store.state.user.token.token
}catch(err){
var token = ""
}
return axios.create({
baseURL: "http://localhost:3333/api/v1",
headers: {
"Authorization": `Bearer ${token}`
}
})
}
After some fiddling, I have worked it out.
You have to first create an axios object with axios.create(), then assign your intercepters to the object after which you can return the object. Here is the code I used that worked.
var axiosInstance = axios.create({
baseURL: "http://localhost:3333/api/v1",
headers: {
"Authorization": `Bearer ${token}`
},
})
//This allows you to intercept the request before it is sent and alter headers or anyting else that is passed to the axios config.
axiosInstance.interceptors.request.use((config)=>{
return config
}, (error) => {
console.log("Interceptor Request Error" + error)
})
//This allows you to intercept the response and check the status and error messages and if ncessary reject the promise.
axiosInstance.interceptors.response.use((response) => {
console.log(response.data)
return response
}, (error) => {
console.log("Interceptor Response Error" + error)
})
return axiosInstance
Now I know how to do this, I could move my Authorization code out of the create function and put it in the request interceptor axiosInstance.interceptors.request.use

How can I do refresh auth token logiс with axios for multiple requests?

I was trying to do it like this, but for three requests it sends three refresh requests:
1, 2, 3 fails with 401
refresh success, 1 success, 2, 3 fails
refresh success, 2 success, 3 fails
refresh success 3 success
I can't put that much load on a mobile device (even if there was only 3 refresh without "refail")
Here is my code:
function requestRefreshToken(refreshToken, accessToken) {
return axios
.create({
baseURL: apiUrl + Endpoints.AUTH.REFRESH,
skipAuthRefresh: true,
headers: {
'Accept-Language': 'ru',
'User-Agent': `${Platform.OS} ${packageJson.version}`,
Authorization: accessToken,
},
})
.post(
'',
{
grant_type: GrantTypes.REFRESH_TOKEN,
refresh_token: refreshToken,
client_id: Client.id,
client_secret: Client.secret,
},
{ validateStatus },
);
}
const refreshAuthLogic = async failedRequest =>
Keychain.getCredentials()
.then(old => requestRefreshToken(old.refreshToken, old.accessToken))
.then(({ data: credentials }) => {
failedRequest.config.headers.Authorization = `${credentials.token_type} ${
credentials.access_token
}`;
return Keychain.setCredentials(credentials);
});
createAuthRefreshInterceptor(axios, refreshAuthLogic, {
retryInstance: axios,
skipWhileRefreshing: true,
onRetry: function(config) {
return Keychain.getCredentials().then(({ accessToken }) =>
axios({
...config,
header: { ...config.headers, Authorization: accessToken },
}),
);
},
});
axios.interceptors.response.use(
r => r,
request => {
if (request.response.status === 401) {
return Keychain.getCredentials().then(({ accessToken }) =>
axios({
...request.config,
header: { ...request.config.headers, Authorization: accessToken },
}),
);
}
},
);
Solved with this! Seems there is no way solving it without failed request queue( https://gist.github.com/mkjiau/650013a99c341c9f23ca00ccb213db1c
Here's a quick way I implemented it.
I found it a bit simpler to reason about the code.
I've adapted it from this solution:
HERE
let refreshTokenPromise: null | Promise < any > ;
instance.interceptors.response.use(r => {
const {
data
} = r;
if (data.errors && data.errors[0].message === "AUTH_EXPIRED") {
if (!refreshTokenPromise) {
refreshTokenPromise = fetchRefreshToken().then(data => {
refreshTokenPromise = null;
return data;
});
}
return refreshTokenPromise.then(token => {
if (r.config.headers) r.config.headers["Authorization"] = token;
return instance.request(r.config);
});
}
return r;
});

Fetch Status Code from restful webservice

I am not able to just fetch the status code from a restful webservice. The web service is just responding with 201 or 401. I am pretty new to react native and I just stuck for hours now.
I am calling the this function in another component. The response I am receiving is always LOG {"_40": 0, "_55": null, "_65": 0, "_72": null}
export default class forgotPasswordCall extends Component {
_forgotPassword = async (username, email) => {
let bodyData = {
'username': username,
'email': email,
}
try {
const response = await fetch('webserviceURL', {
method: "POST",
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
},
body: JSON.stringify(bodyData)
})
return response.status;
}
catch (error) {
console.error(error);
}
}
}
I would need to receive the status code itself.
I would highly recommend using axios instead of fetch. You should try it !

Axios OPTIONS instead of POST Request. Express Rest API (CORS)

Im trying to use Axios (and VueJs) to make a Cross Origin POST Request to my Rest Api (running on localhost). Instead of doing a POST request, it actually does a OPTIONS request to my Rest Api. This circumvents a middleware function that checks for a token and return 403.
This is the login function
router.post('/login', (req, res) => {
User.authUser(req.body, (err, user) => {
var passwordIsValid = bcrypt.compareSync(req.body.password, user.password);
if (err) throw err;
if (!user) {
res.json({ success: false, message: 'User nicht gefunden' });
} else if (user) {
if (!passwordIsValid) {
res.json({ success: false, message: 'Falsches Passwort' });
} else {
const payload = {
admin: user.admin
};
var token = jwt.sign(payload, config.secret, {
expiresIn: 86400
});
res.json({success: true, message: 'Token!', token: token});
}
}
})
});
How can I get Axios to make a proper POST request? I tried this hack, because I first thought the OPTIONS Request was just a preflight, but there is no request after I return 200 (or 204)
CORS Middleware:
app.use(function(req, res, next) { //set Response Headers
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
if ('OPTIONS' == req.method) {
res.send(204);
}
else {
next();
}
});
Axios will sometimes send an OPTIONS request as part of a cors preflight if it doesn't know the Content-Type of a request.
You can get explicitly specify the Content-Type when you build the request, and then it should send your POST request as expected.
Instead of
axios.post(url, params), try:
axios.post(url, params, {
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
})