i have a interceptor with axios but i don't know where to ubicate it. i attach javascript
import axios from 'axios';
import {getStoreData, checkStoreData} from './../utils/safestorage';
axios.interceptors.request.use(
async config => {
console.log('interceptor working');
const checkUser = await checkStoreData('user');
if (checkUser) {
const data = await getStoreData('user');
datajson = JSON.parse(data);
config.headers.Authorization = `Bearer ${datajson.access_token}`;
return config;
}
},
error => {
return Promise.reject(error);
},
);
I solved it importing the file in my app.js, an then my interceptors initialized.
Related
Here is my code
import axios from "axios";
import AuthService from "./auth";
import * as SecureStore from "expo-secure-store";
const API_URL = "MYURL";
const instance = axios.create({
baseURL: API_URL,
token: await SecureStore.getItemAsync("token"),
timeout: 1000,
});
const ServiceMiddleware = {
post: async (url, data) => {
const res = await axios.post(API_URL + url, data);
return res.data;
},
get: async (url, req) => {
const res = await instance.get(url, { params: req });
return res.data;
},
put: async (url, data) => {
const res = await axios.put(API_URL + url, data);
return res.data;
},
delete: async (url) => {
const res = await axios.delete(API_URL + url);
return res.data;
},
};
export default ServiceMiddleware;
I would like to call Expo Secure Store in service middleware to get the token, but when I try to launch the application it gives me error.
I try to implement axios interceptor, for my request.
So when the error response is forbidden (401), I want to clear token and navigate to login screen.
But when I want to call useNavigation from react navigation v5 inside my axios file, it always shows error like this.
React Hook "useNavigation" is called in function "refreshAccessToken" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter.
This is my axios file code,
import axios from 'axios'
import AsyncStorage from '#react-native-community/async-storage'
import {useNavigation} from '#react-navigation/native'
import {generateRandomString, getDeviceInfo} from '../helper/helper'
const base = axios.create({
baseURL: '------',
timeout: 500000,
headers: {
'Content-Type': 'application/json'
}
})
async function refreshAccessToken() {
const navigation = useNavigation()
try {
const refreshToken = await AsyncStorage.getItem('refreshToken')
const response = await base.get('------', {
refreshToken
})
await AsyncStorage.setItem('accessToken', response.data.accessToken)
console.log('Response from refresh access token ', response)
return Promise.resolve(response.data)
} catch (error) {
console.log('Error from refresh access token', error.response)
if (error.response.data.errors.flag === 'INVALID_REFRESH_TOKEN') {
await AsyncStorage.removeItem('refreshToken')
await AsyncStorage.removeItem('accessToken')
}
return Promise.reject(error)
}
}
base.interceptors.request.use(
async function (config) {
const accessToken = await AsyncStorage.getItem('accessToken')
config.headers.authorization = accessToken
const deviceInfo = await getDeviceInfo()
const latitude = await AsyncStorage.getItem('latitude')
const longitude = await AsyncStorage.getItem('longitude')
config.headers['accept-language'] = 'id-ID'
config.headers['version'] = '1.0.0'
config.headers['date'] = new Date().toUTCString()
config.headers['x-coordinate'] = `${latitude};${longitude}`
config.headers['x-trace-id'] = generateRandomString()
config.headers['x-device'] = `${deviceInfo.deviceType}/${deviceInfo.deviceName}/${deviceInfo.deviceVersion}/${deviceInfo.deviceUid}`
return config
},
function (error) {
return Promise.reject(error)
}
)
base.interceptors.response.use(
(response) => response,
async (error) => {
const originalRequest = error.config
if (error.response.status === 403 && !originalRequest._retry) {
originalRequest._retry = true
const accessToken = await refreshAccessToken()
originalRequest.headers.Authorization = accessToken
return axios(originalRequest)
}
return Promise.reject(error)
}
)
export default base
You can't, hooks are only meant to be called inside components. There is a guide on how to navigate without the navigation prop you could use for this situation though.
You could also send an event (via a custom event emitter) and set up a listener anywhere else in your app where the navigation prop is available.
Problem:
In my react native app in order to remove repeated calls I have developed a general POST GET methods in httpClient file. It code is look likes this.
import axios from 'axios';
import AsyncStorage from '#react-native-community/async-storage';
axios.defaults.headers.post['Content-Type'] = 'application/json';
var instance = null;
const setAuthorisationHeder = async () => {
const token = JSON.parse(await AsyncStorage.getItem('auth_data'));
if (token) {
console.log('>>>>>> instance', instance);
Object.assign(instance.headers, {
Authorization: 'Bearer' + token.accessToken,
});
} else {
console.log('>>>>>> instance', instance);
Object.assign(instance.headers, {
Authorization: '',
});
}
};
export const setHeader = () => {
console.log('>>>>>>>> HIIII');
instance = axios.create({
baseURL: '',
timeout: 150000,
headers: {
'Content-Type': 'application/json',
},
});
instance.interceptors.response.use(
function (response) {
return response;
},
async function (error) {
if (error.response.status) {
if (error.response.status === 401) {
AsyncStorage.removeItem('auth_data');
} else {
throw error;
}
} else {
console.log(error);
}
},
);
};
export const Get = (route, data) => {
function getData() {
return instance.get(
route,
data == null ? {data: {}} : {data: JSON.stringify(data)},
);
}
if (instance) {
console.log('>>>>>> HIIIIii');
// setAuthorisationHeder();
return getData();
}
return setHeader().then(getData);
};
export const Post = (route, data) => {
console.log('>>>>>> route', route);
function postData() {
return instance.post(route, JSON.stringify(data));
}
if (instance) {
console.log('>>>>>> HIIIIii');
// setAuthorisationHeder();
// setAuthorisationHeder();
return postData();
}
return setHeader().then(postData);
};
Can some tell me a way to add an authorization header to this instance? My token is storing the Asyncstorage in the middle of some actions so at the beginning called I don't have the token. As my code setHeader is running only one time so I created a method call setAuthorisationHeder() function. But it is giving me can not find property .then error when I am putting a request. Can someone help me to solve this issue? Thank you?
you can define global headers once and use it in every network call.
https://github.com/axios/axios#global-axios-defaults
Create a global auth variable where you'll store the auth data from storage. Before making a request get the auth data and use interceptor to set the bearer token.
let authToken = '';
const getAuthToken = async () => {
// asumming auth token was saved as string
authToken = await AsyncStorage.getItem('auth_data');
};
Interceptor
// request interceptor
axiosInstance.interceptors.request.use(
function (config) {
// Do something before request is sent
config.headers.Authorization = `Bearer ${authToken}`;
return config;
},
function (error) {
// Do something with request error
return Promise.reject(error);
}
);
complete code
import axios from 'axios';
import AsyncStorage from '#react-native-community/async-storage';
let authToken = '';
const axiosInstance = axios.create({
baseURL: '',
timeout: 150000,
headers: {
'Content-Type': 'application/json',
},
});
// request interceptor
axiosInstance.interceptors.request.use(
function (config) {
// Do something before request is sent
config.headers.Authorization = `Bearer ${authToken}`;
return config;
},
function (error) {
// Do something with request error
return Promise.reject(error);
}
);
const getAuthToken = async () => {
// asumming auth token was saved as string
authToken = await AsyncStorage.getItem('auth_data');
};
export const Get = async (route, data = {}) => {
// get and set auth token
await getAuthToken();
// route = /user?id=787878 or /user/787878
return await axiosInstance.get(route);
};
export const Post = async (route, data = {}) => {
await getAuthToken();
return await axiosInstance.post(route, data);
};
I'm trying to send the Authorization header inside of all requests, when user is logged in my application.
but, whatever i do, it does not work.
Here is my axios instance and interceptor code.
import axios from 'axios'
import storage from '#/services/storageService'
const user = storage.getObject('currentUser')
export const http = axios.create({
baseURL: 'http://localhost/api',
})
http.interceptors.request.use((config) => {
if(user){
console.log(user)
config.headers.Authorization = user.token
}
return config
}, (err) => {
console.log(err)
return Promise.reject(err)
})
in my modules i'm importing the http instance like this
import { http } from '#/http'
export const getItems = () => {
return http.get('items').then( response => response.data)
}
So, clarifying, this code above works, but the header is not present on my request.
To get the interceptor working i need to force a page reload.
Anyone know how can i avoid this?
I solved my problem following #jacky's tip. Now my code runs as following.
import axios from 'axios'
import storage from '#/services/storageService'
export const http = axios.create({
baseURL: 'http://localhost/api',
})
http.interceptors.request.use((config) => {
let user = storage.getObject('currentUser')
if(user){
console.log(user)
config.headers.Authorization = user.token
}
return config
}, (err) => {
console.log(err)
return Promise.reject(err)
})
I did create a service for authentication in vuejs
import axios from "axios";
var authenticateService = {
login: function(Username, Password) {
var form = new FormData();
form.append("username", Username);
form.append("password", Password);
return axios.post(LOGIN_API, form);
}
}
export default authenticateService;
I want to use this service in my main.js, where I have got an axios interceptor. I have interceptor which relogins if received any 401 response from server
import authenticateService from "./service/AuthenticationService";
import axios from "axios";
axios.interceptors.response.use(undefined, err => {
let res = err.response;
if (res.status === 401 && res.config && !res.config.__isRetryRequest) {
return new Promise((resolve, reject) => {
authenticateService//Error here. authenticateService undefined
.login('user1username', 'user1password')
.then(result => {
localStorage.setItem("expire_time", response.data.expires_in);
localStorage.setItem("access_token", response.data.access_token);
err.config.__isRetryRequest = true;
err.config.headers.Authorization =
"Bearer " + response.data.access_token;
resolve(err);
})
.catch(e => {
localStorage.removeItem("expire_time");
localStorage.removeItem("access_token");
reject(e);
});
});
}
});
This interceptor throws error saying "authenticateService is not defined". Though I have imported the authenticateService, I get it undefined. Not sure what I did wrong here.
Edit return axios object from login function