I tried implement logout function with axios post in vue. I add the jwt to request headers, but it treated as params. In another function, i implement axios post method and it works. Anybody can help ? This is the code :
import axios from 'axios';
import store from '../store';
const API = 'http://192.168.100.184:5000/api/v1.0.0';
export class APIService{
constructor(){
}
login (userData) {
return axios.post(`${API}/auth/`, userData);
}
logout(){
const url = `${API}/auth/logout`;
const headers = {"api_token": store.state.jwt};
return axios.post(url,{headers:headers});
}
createUser(user){
const headers = {"api_token": store.state.jwt};
const url = `${API}/user/`;
return axios.post(url,user,{headers: headers});
}
}
when i see the network, in the request headers of createUsermethod there api_token field and it success. But in request headers of logout method there no api_token field, the api_token is found in the params and it looks like :
headers{…}
api_token : xxxxxxxx
the response say error with status code 400.
This:
return axios.post(url,{headers:headers});
should be this:
return axios.post(url, null, {headers: headers});
The second parameter must be the request body, the third parameter is for other options such as the headers.
Related
I'm trying to use axios and axios-mock-adapter in one place to aggregate more mocks and then export the axios instance to use it wherever I want:
axios.js
import axios from 'axios';
let api = axios.create({
baseURL: 'http://localhost:3500',
});
export default api
Login.js
import api from '../../../api/axios';
import MockAdapter from 'axios-mock-adapter';
let mock = new MockAdapter(api);
const LOGIN_URL = '/users';
const onSubmit = async data => {
console.log(data);
const user = data.loginEmail;
const pwd = data.password
const response = await mock.onPost(LOGIN_URL,
JSON.stringify({ user, pwd }),
{
headers: { 'Content-Type': 'application/json' },
withCredentials: true
}
);
console.log(response);
}
But I get this response:
{reply: ƒ, replyOnce: ƒ, passThrough: ƒ, abortRequest:ƒ,abortRequestOnce: ƒ, …}abortRequest: ƒ ()abortRequestOnce: ƒ()networkError: ƒ ()networkErrorOnce: ƒ ()passThrough: ƒ passThrough()reply: ƒ reply(code, response, headers)replyOnce: ƒ replyOnce(code, response, headers)timeout: ƒ ()timeoutOnce: ƒ ([[Prototype]]: Object
Can anyone help me? What did I miss?
It sends status 200 but it doesn't send any request to the server and it's like not connecting to the server
It looks like you're trying to mock a GET request to the '/users' endpoint with the axios-mock-adapter, but in your onSubmit function you are making a POST request to the same endpoint. That's why you're getting a 404 error.
You can either change the mock.onGet to mock.onPost or change the onSubmit function to make a GET request.
Also, you should check the baseURL that you are using in the axios.create() method in axios.js and make sure it's the correct one.
Also, check if you have setup your server properly and it's running on the correct port.
If you continue to have issues you might want to check the browser's devtools network tab and check the request being made and the corresponding response.
axios.js
import axios from 'axios';
let api = axios.create({
baseURL: 'http://localhost:3500',
});
export default api
The solution was about to change the Login.js
// ** API
import api from '#api';
const LOGIN_URL = '/auth'
And onSubmit Event
// !! On Submit Event
const onSubmit = async data => {
const user = data.username;
const pass = data.password;
try {
const response = await api.post(LOGIN_URL,
JSON.stringify({ user, pass }),
{
headers: { 'Content-Type': 'application/json' },
withCredentials: true
}
);
.
.
.
}
I have following react code to make call to django rest framework API:
import Cookies from 'js-cookie';
import axios from "axios";
async downloadVideowiseCSV (fromDate, toDate) {
var url = '/stat/getStats/';
const axiosInstance = axios.create();
try {
const response = await axiosInstance.post(url,
{
data: {
'format': 'json'
},
header: {
'X-CSRFToken': Cookies.get('csrftoken')
}
}
)
//...
}
When this method gets called, the corresponding request fails with CSRF verification:
However when I check the payload of the request, I could see that X-CSRFTOken is indeed populated:
Then whats going wrong here?
The problem is in your axios request, it's not correct to send the header in the body of the HTTP request.
The following should be a valid axios request which separates the data from the options
ex:
const config = {
headers: { 'X-CSRFToken': Cookies.get('csrftoken') },
};
const data = {format: 'json'}
axios.post('http://YOUR_URL', data, config)
.then((response) => {
console.log(response.data);
});
I have a form that uses axios to send a post request. The problem is that the request is being sent with a header of Content-Type: multipart/form-data. My nodejs api does not like this and gives me an undefined req.body.
I have other forms that use the same techniques and they work and the header is as expected with: Content-Type: application/json;charset=UTF-8
The form that is posting Content-Type: multipart/form-data does not have any images. Just text input fields.
If I try to set the form headers manually they are ignored. Why would one form send standard 'application/json' and another form send 'multipart/form-data'?
Here is the form in pug:
form.form.form-send-cert-data
.form__group
label.form__label(for='name') Recipients Name
input#name.form__input(type='text', required, name='name')
.form__group
label.form__label(for='email') Recipient Email
input#email.form__input(type='text', required, name='email')
.form__group
label.form__label(for='plantId') Plant
select(name='plantId', id='plantId')
each val in ['5f1133ca79232fab1ffe5be4' , '5f113d3944221b47f577c239' , '5f113e019f4aa448a253ed87']
option=val
.form__group
label.form__label(for='message') Message
input#message.form__input(type='text', required, name='message')
.form__group.right
button.btn.btn--small.btn--green Send Certificate
Here is how I prep the form data for the post:
addCertificateForm.addEventListener('submit', (e) => {
e.preventDefault();
const form = new FormData();
form.append('name', document.getElementById('name').value);
form.append('email', document.getElementById('email').value);
form.append('message', document.getElementById('message').value);
form.append('plantId', document.getElementById('plantId').value);
console.log('-Send Certificate-');
sendCertificate(form, 'data');
});
Here is sendCertificate.js:
import axios from 'axios';
import { showAlert } from './alerts';
export const sendCertificate = async (data, type) => {
console.log('sendCertificate.js');
try {
const url = '/api/v1/certificates/send';
const res = await axios({
method: 'POST',
url,
data,
});
if (res.data.status === 'success') {
showAlert('success', `${type.toUpperCase()} sent successfully!`);
}
} catch (err) {
showAlert('error', err.response.data.message);
}
};
Since you aren't sending any files that must be sent using FormData you can easily build an object to pass to axios which will send as json
addCertificateForm.addEventListener('submit', (e) => {
e.preventDefault();
const postData = {};
const keys = ['name', 'email', 'message', 'plantId'];
keys.forEach(k => postData[k] = document.getElementById(k).value)
sendCertificate(postData, 'data');
});
Note I haven't used Axios for years and don't remember if you need to set json content-type header or if it is set by default
I have components that are making get requests in their created methods. I am using oidc client for authorization. I would like to set the each request header with the token that I get from oidc. I have made a http.js file in the root of the project, that looks like this:
import axios from 'axios';
import AuthService from "./AuthService";
const authService = new AuthService();
let token;
axios.interceptors.request.use(async function (config) {
await authService.getUser().then(res => {
if (res) {
token = res.id_token;
config.headers['Authorization'] = `Bearer ${token}`;
}
});
// eslint-disable-next-line no-console
console.log('interceptor', config);
return config;
}, function (error) {
// Do something with request error
return Promise.reject(error);
});
I am not sure if this is the way to set the interceptors and how to actually use them, because on each request I see that they are not being set and nothing is being logged in the console. How is this suppose to be set up?
So I have an API and I am trying to authenticate by hitting an endpoint with credentials (this part I've gotten working) and then save the received token and use it in all subsequent requests.
My problem is that the authenticate() method is asynchronous, but all other request methods like get() need the token from the authenticate() method. So I can't just export my get() method because the export is synchronous (as I've read) and it will be exported before authentication happens. I could authenticate for every request but that seems wasteful and inefficient.
I am not sure what to do here, I'm using axios, what's the proper way of doing this?
Edit
I'll be a bit more specific here. I have created an axios instance:
var instance = axios.create({
baseURL: `http://${config.server}:${config.port}`,
timeout: 1000,
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
})
I want to get the authentication token, and include it in the instance header:
async function authenticate(instance) {
const result = await instance.post(
'/session',
{
'username': config.username,
'password': config.password
}
)
instance['X-Token'] = result.data.token
}
Now I want to export that instance to be used in other files
You can use async/await. This is semi-pseudocode:
async function doStuff() {
const result = await axios.authenticate();
const token = // extract token from whatever format of result is
const data = await axios.get(/* supply token to get */);
}
Alternatively, you can just use then:
function doStuff(token) {
const token = // extract token from whatever format of result is
const data = await axios.get(/* supply token to get */);
}
axios.authenticate().then(result => {
const token = // extract token from whatever format of result is
doStuff(token);
}
With Axios you have the ability to set default values for all requests.
So for just a single axios instance you can do...
async function authenticate(instance) {
const result = await instance.post(
'/session',
{
'username': config.username,
'password': config.password
}
)
instance.defaults.headers.common['X-Token'] = result.data.token;
}
Alternatively, (which it sounds like you want to do) you can add it for the default Axios export. Then all requests will automatically have the header.
async function authenticate(endpoint, username, password) {
const res = await axios.post(`${endpoint}/session`, { username, password });
axios.defaults.headers.common['X-Token'] = result.data.token;
}
Then you don't have to worry about passing around an instance between all parts of your app and can just use import * as axios from 'axios' and have the header set.
Axios also provides and extremely helpful function called interceptors which you can use to inspect a request prior to making it. You can use to check to make sure that the request has the auth header and if it doesn't you can perform that logic. I came up with this and it seems to work well!
axios.interceptors.request.use(async (config) => {
// request intercepted, check (1) the header is missing and (2) that the intercepted request isn't authorizing
if (!config.headers.common['X-Token'] && config.authorizing !== true) {
const { endpoint, username, password } = appConfig;
// make a request to get your token AND pass our custom config
const result = await axios.post(`${endpoint}/session`, { username, password }, { authorizing: true });
// update axios to include the header for future requests
axios.defaults.headers.common['X-Token'] = result.data.token;
}
return config;
});
Two things that you'll want to note -- not only do I check for the existence of your X-token header I also check for a new authorization value in the config. You want to check for that config value, because we are going to use it as a flag to let the interceptor know if it should skip a request. If you don't do this, the authorization request will trigger another authorization request and infinite loop.