I am trying to authenticate user using Auth0. Once they have signed in, I would like to obtain the data and store it in my database. If the user exist after authentication, I would like to obtain the relevant product data from my user. But if it does not exist, I would like to axios.post in my database. The problem is now I could not post the data as I do not know what is wrong.
Here is the homepage:
import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";
import axios from "axios";
import { Routes, Route } from "react-router-dom";
import { useAuth0 } from "#auth0/auth0-react";
export default function Homepage() {
const [userList, setUserList] = useState([]);
const getUser = () => {
// Sending HTTP GET request
const accessToken = getAccessTokenSilently({
audience: process.env.REACT_APP_AUDIENCE,
scope: process.env.REACT_APP_SCOPE,
});
axios
.get(`${process.env.REACT_APP_API_SERVER}/users`, {
headers: {
Authorization: `Bearer eXg`,
},
})
.then((response) => {
const userNames = response.data.map((res) => res.name);
setUserExist(userExist);
});
};
const {
loginWithRedirect,
user,
isAuthenticated,
getAccessTokenSilently,
logout,
} = useAuth0();
useEffect(() => {
// If there is a user, retrieve the user data
if (user) {
const accessToken = getAccessTokenSilently({
audience: process.env.REACT_APP_AUDIENCE,
scope: process.env.REACT_APP_SCOPE,
});
axios
.get(`${process.env.REACT_APP_API_SERVER}/users`, {
headers: {
authorization: `Bearer eXg`,
},
})
.then((response) => {
setUserList(response.data);
});
} else loginWithRedirect();
}, []);
useEffect(() => {
if (isAuthenticated) {
console.log(user);
getUser();
console.log(userList);
//Check to see if curr user exists
if (userList.includes(user.name.trim())) {
console.log("already existed");
const accessToken = getAccessTokenSilently({
audience: process.env.REACT_APP_AUDIENCE,
scope: process.env.REACT_APP_SCOPE,
}); axios.get(`${process.env.REACT_APP_API_SERVER}/products/users/${userId}`, {
headers: {
Authorization: `Bearer eXg`,
},
});
}
//else post user to database
else {
const accessToken = getAccessTokenSilently({
audience: process.env.REACT_APP_AUDIENCE,
scope: process.env.REACT_APP_SCOPE,
});
axios
.post(
`${process.env.REACT_APP_API_SERVER}/users`,
{
firstName: user.nickname,
lastName: user.nickname,
email: user.email,
},
{
headers: {
authorization: `Bearer eXg`,
},
}
)
.then((response) => {
});
}
} else loginWithRedirect();
}, []);
return (
<div>
Hi
</div>
);
}
My backend is showing that it managed to add the user but my database is not showing anything.
Related
My question is related to customAxios.interceptors.response.use . My purpose here is; if the token expired and I got a 401 error, make a request again where I got a 401 error and write the new token to the headers. On the other hand, if I get an error except for the 401 error, show me the error.response.data . Do you think this logic is set up correctly? I tried to test but I wasn't sure especially 401 error cases
import axios from "axios";
import { LoginAPI } from "../playwright/tests/login/login.api";
import { test } from "#playwright/test"
import {configEnv} from "../config/config"
test.beforeAll(async () => {
await LoginAPI.API.Signin.run()
});
const customAxios = axios.create({
baseURL: configEnv.apiBaseURL
});
customAxios.interceptors.request.use(
async (config) => {
if (config.headers) {
config.headers['Authorization'] = `Bearer ${LoginAPI.States.token}`;
return config;
}
return config;
},
(error) => {
Promise.reject(error);
}
);
customAxios.interceptors.response.use(
function(response) {
return response;
},
async function(error) {
if (401 === error.response.status) {
await LoginAPI.API.Signin.run()
customAxios.defaults.headers.common['Authorization'] = `Bearer ${LoginAPI.States.token}`
} else {
return Promise.reject(error.response.data);
}
}
);
export default customAxios
I would recommend you to store your token in a localStorage and then replace it after refresh. This way you can set a token in your API class in one place.
import axios from "axios";
export const ApiClient = () => {
// Create a new axios instance
const api = axios.create({
baseURL: "URL",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
});
// Add a request interceptor to add the JWT token to the authorization header
api.interceptors.request.use(
(config) => {
const token = sessionStorage.getItem("jwtToken");
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => Promise.reject(error)
);
// Add a response interceptor to refresh the JWT token if it's expired
api.interceptors.response.use(
(response) => response,
(error) => {
const originalRequest = error.config;
// If the error is a 401 and we have a refresh token, refresh the JWT token
if (
error.response.status === 401 &&
sessionStorage.getItem("refreshToken")
) {
const refreshToken = sessionStorage.getItem("refreshToken");
let data = JSON.stringify({
refresh_token: refreshToken,
});
post("/refreshToken", data)
.then((response) => {
sessionStorage.setItem("jwtToken", response.token);
sessionStorage.setItem("refreshToken", response.refresh_token);
// Re-run the original request that was intercepted
originalRequest.headers.Authorization = `Bearer ${response.token}`;
api(originalRequest)
.then((response) => {
return response.data;
})
.catch((error) => {
console.log(error);
});
// return api(originalRequest)
})
.catch((err) => {
// If there is an error refreshing the token, log out the user
console.log(err);
});
}
// Return the original error if we can't handle it
return Promise.reject(error);
}
);
const login = (email, password) => {
return api
.post("/authentication_token", { email, password })
.then(({ data }) => {
// Store the JWT and refresh tokens in session storage
sessionStorage.setItem("jwtToken", data.token);
sessionStorage.setItem("refreshToken", data.refresh_token);
})
.catch((err) => {
// Return the error if the request fails
return err;
});
};
const get = (path) => {
return api.get(path).then((response) => response.data);
};
const post = (path, data) => {
return api.post(path, data).then((response) => response.data);
};
const put = (path, data) => {
return api.put(path, data).then((response) => response.data);
};
const del = (path) => {
return api.delete(path).then((response) => response);
};
return {
login,
get,
post,
put,
del,
};
};
Best,
Chris
I am having a config file . where i am setting the baseURL for the entire app and also saving the bearer token for the entire API requests. Here i am in situation to add another api . I dont know how to add another baseURL & use this on my API requests.Here i am sharing the code of what i have done.
BASE URL FILE:
import axios from 'axios';
axios.defaults.baseURL = http://localhost:3000/summary;
const setAuthToken = (token) => {
if (token) {
axios.defaults.headers.common.Authorization = `Bearer ${token}`;
} else {
delete axios.defaults.headers.common.Authorization;
}
};
export default setAuthToken;
API ACTION FILE:
export const login = ({ email, password }) => async (dispatch) => {
const userData = {
username: email,
password,
};
try {
const res = await axios.post('/license-api/auth/login', userData, config);
dispatch({
type: LOGIN_SUCCESS,
payload: res.data.token,
});
} catch (error) {
dispatch({
type: LOGIN_FAIL,
});
}
};
i need to add another url like this in BASE URL FILE
axios.defaults.baseURL = http://localhost:6000/profile
how to add this one and use this in API action file.
Please help me with this.
Thanks in advance
As said you could create two instances of axios and use them as needed:
In you BASE URL file:
import axios from 'axios';
const setAuthToken = (token) => {
if (token) {
axios.defaults.headers.common.Authorization = `Bearer ${token}`;
} else {
delete axios.defaults.headers.common.Authorization;
}
};
const mainAxios = axios.create({
baseURL: 'http://localhost:3000/summary'
});
const profileAxios = axios.create({
baseURL: 'http://localhost:6000/profile'
});
export default setAuthToken;
export { mainAxios, profileAxios };
Then in your API ACTION file:
import { profileAxios } from 'path/to/baseurl';
export const login = ({ email, password }) => async (dispatch) => {
const userData = {
username: email,
password,
};
try {
const res = await profileAxios.post('/license-api/auth/login', userData, config);
dispatch({
type: LOGIN_SUCCESS,
payload: res.data.token,
});
} catch (error) {
dispatch({
type: LOGIN_FAIL,
});
}
};
The above code works well. I don't see where setAuthToken is called so if you don't want to call setAuthToken manually then you might want to do this.
import axios from "axios";
import { config } from "./config";
const pythonAPI = axios.create({
baseURL: config.pythonServerUrl,
});
const nodeApi = axios.create({
baseURL: config.nodeServerUrl,
});
const setToken = () => {
const token = localStorage.getItem("auth_token");
if (token) {
pythonAPI.defaults.headers.common.Authorization = `Basic ${token}`;
} else {
delete pythonAPI.defaults.headers.common.Authorization;
}
};
const pythonApi = {};
pythonApi.get = async (url) => {
setToken();
return pythonAPI.get(url).catch((e) => e.response);
};
pythonApi.post = async (url, data) => {
setToken();
return pythonAPI.post(url, data).catch((e) => e.response);
};
export { pythonApi, nodeApi };
Where can i put the Authorization header token in axios after dispatching login action with laravel passport authentication in a seprated vue.js project?I tried with setting it in main.js like this and doesnt work properly. After dispatching, In the QuestionIndex component, the axios call dont have the authorization header automatically. And by refreshing the page, it has the authorization header. I can fix this by putting the token header in QuestionIndex Component. But I dont think this is a proper way to do it. Please help me with this problem.
In main.js
const token = localStorage.getItem('access_token');
if (token) {
axios.defaults.headers.common['Authorization'] = 'Bearer ' + token;
}
In login.vue
login(){
this.$store
.dispatch("login", this.form)
.then(() => {
this.$router.push({ name: "QuestionIndex" });
})
.catch(err => {
console.log(err);
});
}
In vuex store
state: {
token: localStorage.getItem('access_token') || null,
user: {},
},
mutations: {
setToken(state, data) {
state.token = data.token;
state.user = data.user;
},
},
actions: {
login({ commit }, credentials) {
return axios.post("http://127.0.0.1:8000/api/login", credentials).then(( res ) => {
localStorage.setItem('access_token', res.data.data.token);
commit("setToken", res.data.data);
});
},
},
getters: {
token: (state) => state.token,
}
You can set the Authorization header after initializing the axios instance like this:
axiosInstance.interceptors.request.use((config) => {
const token = localStorage.getItem('access_token');
config.headers.Authorization = `Bearer ${token}`
return config
})
In your VUEX action, make sure to use the axiosInstance you created in your main.js (or whereever). If you just import axios in your VUEX store like this import axios from 'axios' it will not work, because it's not the axios instance you set the header on.
you can try this
axios.post("http://127.0.0.1:8000/api/login", credentials, { headers: { Authorization: 'Bearer ' + localStorage.getItem('access_token') } })
Im new at Vue and im trying to make a Request HTTP to my backend,
When i inspect in my browser, i get the access token from /login but in the api/users i get "Token is Invalid". How do i get my api/users data?
import axios from "axios";
export default {
name: "login",
async created() {
const response = await axios.get("api/users", {
headers: {
Authorization: "Bearer " + localStorage.getItem("token")
}
});
console.log(response);
},
data() {
return {
showError: false,
email: "",
password: "",
};
},
methods: {
async EnvioLogin() {
try {
const response = await axios.post("api/auth/login", {
email: this.email,
password: this.password,
});
localStorage.setItem("token", response.data.token);
const status = JSON.parse(response.status);
if (status == "200") {
console.log(response);
this.$router.push("intermediorotas");
}
} catch (error) {
this.showError = true;
setTimeout(() => {
this.showError = false;
}, 3000);
}
},
},
You can create a service to make call to backend, i guess the problem is the url http://localhots:3000/api, you missed this part http://localhots:3000
import axios from 'axios'
const client = axios.create({
baseURL: 'http://localhots:3000/api',
headers: {
'Content-Type': 'application/json',
},
})
export default client
then import the service
import myService from './myService'
await myService.get(`/auth/login`, {})
I am writing code to call api using axios. So, for this code I have to send an otp to the api along with an authorization token. I am using vuex store.
I am getting an error of 406(not applicable). This is the code I have written.
import { isAuthenticated } from './auth'
import axios from 'axios'
export default ({
state: {
},
mutations: {
},
getters: {
},
actions: {
VERIFY: (payload) => {
const userId = isAuthenticated().user._id
return axios
.post(apilink, payload, {
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${isAuthenticated().token}`,
Accept: 'application/json'
}
}).then(response => {
console.log(response)
return response.data
})
.catch(error => {
if (error) {
console.log(error)
}
})
}
},
modules: {
}
})
<template>
<mdb-btn color="info" #click="verify()">Verify</mdb-btn>
</template>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js">
data () {
return {
value: ''
}
},
methods: {
verify () {
this.$store.dispatch('VERIFY', {
otp: this.value
}).then(success => {
console.log(success)
}).catch(error => {
console.log(error)
})
}
}
</script>
I think it's the problem with authorization part. Please help me.
isAuthenticated is funtion used to get data from localStorage
export const isAuthenticated = () => {
if (localStorage.getItem('auth')) {
return JSON.parse(localStorage.getItem('auth'))
}
return false
}
406 error is appearing because of Accept parameter in the header try after removing "Accept: 'application/json'"