How can access $auth.getToken('local') in a service? - vue.js

I am new in nuxtjs.i am trying to create a service like EventService.js.From EventService.js i want to get data using axios. but i want to set Authorization header.But can't get the access token from $auth.getToken('local'). i don't want to set Authorization header every axios request.Thanks
import axios from 'axios'
const apiClient = axios.create({
baseURL: `example.com`,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
'Authorization': "Bearer " + **$auth.getToken('local')**
}
})
export default {
getEvents() {
return apiClient.get('/events')
}
}

axios interceptors solved my problem
apiClient.interceptors.request.use(
(config) => {config.headers["Authorization"] =cookies.get("auth._token.local")
.replace(/%/g, " ")
return config
},
function(error) {
return Promise.reject(error) })

You can import 'axios' in your main.js (entry file) and add the following:
import axios from 'axios'
axios.defaults.headers.common['Authorization'] = `Bearer ${localstorage.getItem('token')}`;
And when you setup your token for the first time, your can set it up on the localstorage and assign again to the axios defaults headers:
import axios from 'axios'
const token = <AUTH_TOKEN>
// when setting the token
localstorage.setItem('token', token)
axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
This will be enough to send the Authorization header in every axios request you make.

Related

Protected route returning malformed request.json() to React frontend

I am trying to make a fetch request to a protected route on my Express app. The route is working fine when the request is made with Postman, I get the response sent. But when I attempt a fetch request from the frontend, I get SyntaxError: Unexpected token A in JSON at position 0.
The fetch request from the frontend
export const getProtectedMessage = async (token) => {
const URI = 'http://localhost:3001'; //TODO save root uri to environment variable
const bearer = 'Bearer ' + token;
return fetch(`${URI}/me`, {
method: 'GET',
withCredentials: true,
credentials: 'include',
headers: {
'Authorization': bearer,
'Content-Type': 'application/json',
'Cache-Control': 'no-cache'
}
})
.then(handleErrors)
.then((res) => res.json())
.catch((err) => {
console.error(err);
});
};
Entry point for express app index.js
import dotenv from 'dotenv';
import express from 'express';
import morgan from 'morgan';
import cors from 'cors';
import routes from './routes/index.js';
import db from './db/index.js';
dotenv.config();
db(process.env.DB_NAME);
const PORT = process.env.PORT || 3001;
const app = express();
app.use(express.json());
app.use(cors({ credentials: true, origin: 'http://localhost:3000' }));
app.use(morgan('dev'));
app.use(routes);
app.get('*', (req, res) => {
res.sendStatus(404);
});
app.listen(process.env.PORT, () => {
console.log(`app listening on port ${PORT}`);
});
The routes
import express from 'express';
import * as auth from '../controllers/auth.js';
import expressjwt from 'express-jwt';
import dotenv from 'dotenv';
dotenv.config();
const router = express.Router();
const jwtCheck = expressjwt({
secret: process.env.SECRET_KEY,
algorithms: ['sha1', 'RS256', 'HS256']
});
router.post('/sign-up', auth.signUp);
router.post('/sign-in', auth.signIn);
router.get('/me', jwtCheck, auth.profile);
export default router;
The controller for the protected route
export function profile(req, res) {
res.status(200).send('A secret resource - only for authenticated users');
}
In the end the error was how I was sending the response. Maybe there's a more appropriate way to do it, but changing the controller to the following worked.
export function profile(req, res) {
// res.status(200).send('A secret resource - only for authenticated users'); // WRONG
res.status(200).json('Resource only for authenticated users'); // works!
}
One more thing, it's also good practice to check the application header in the fetch request. Sometimes, you don't know what you're getting from the backend could be json, could be text.
export const getProtectedMessage = async (token) => {
const URI = 'http://localhost:3001'; //TODO save root uri to environment variable
const bearer = 'Bearer ' + token;
return fetch(`${URI}/me`, {
method: 'GET',
withCredentials: true,
credentials: 'include',
headers: {
Authorization: bearer,
'Content-Type': 'application/json',
'Cache-Control': 'no-cache'
}
})
.then(handleErrors)
.then((res) => {
const contentType = res.headers.get('Content-Type').split(';')[0];
if (contentType === 'application/json') {
return res.json();
}
console.log(contentType);
if (contentType === 'text/html') {
return res.text();
}
})
.catch((err) => {
console.error(err);
});
};

GET http://localhost:3000/api/eventNames net::ERR_CONNECTION_REFUSED

I am trying to get axios working with my vue project so I can test the backend of my app. It seems that I am having issues setting up the axios server as I'm getting a connection refused on the baseURL that I have setup. I posted my api.js file that I created under service/api.js. Any information on things to look at to get this resolved would be greatly appreciated.
/src/service/api.js
import axios from 'axios';
export default () => {
const instance = axios.create({
baseURL: 'http://localhost:3000/api',
withCredentials: false,
headers: {
Accept: "application/json",
"Content-Type": "application/jason"
}
});
return instance;
}

How to solve Cannot read property 'defaults' of undefined in vue?

I am setting default headers in my vue application, but when I load the app it show me error.
main.js?56d7:14 Uncaught TypeError: Cannot read property 'defaults' of undefined
Code
const token = sessionStorage.getItem("token");
if (token) {
Vue.prototype.$http.defaults.header.common["Authorization"] = token;
}
I made a working codepen based on your issue.
In your case, you need to create axios client.
Please check this codepen. https://codepen.io/endmaster0809/pen/VwaPGzr
let apiClient = axios.create({
baseURL: "https://jsonplaceholder.typicode.com",
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
}
})
const token = "testtoken";
if (token) {
apiClient.defaults.headers.common["Authorization"] = token;
}
Vue.prototype.$http = apiClient;

Config Axios globally with Authenticated in NuxtJS - VueJS

I finding way to config Axios globally with Authenticated in NuxtJS - VueJS (I use mainly NUXTJS).
All I need is: If user logged in and have token in $store, axios will get this token. If user is anonymous, axios wont get this token
~/plugins/axios
import axios from 'axios'
import AuthenticationStore from '~/store'
var api = axios.create({
baseURL: 'http://localhost:8000/api/v1/',
'headers': {'Authorization': 'JWT ' + AuthenticationStore.state.token}
})
api.interceptors.request.use(function (config) {
config.headers = {
'Authorization': AuthenticationStore.state.token ? 'JWT ' + AuthenticationStore.state.token : ''
}
return config
}, function (error) {
// Do something with request error
return Promise.reject(error)
})
export default api
~/store/index.js
const AuthenticationStore = () => {
return new Vuex.Store({
state: {
token: null
},
mutations: {
SET_TOKEN: function (state, token) {
state.token = token
instance.defaults.headers = { Authorization: 'Bearer ' + token }
}
},
actions: {
....
}
})
}
export default AuthenticationStore
Error: [nuxt] Error while initializing app TypeError: Cannot read property 'token' of undefined
I would suggest to use interceptor instead which is more flexible and getting token when making request not on creation. Try something like that to avoid issues with not set token.
// ~/plugins/axios
import axios from 'axios'
import AuthenticationStore from '~/store'
var api = axios.create({
baseURL: 'http://localhost:8000/api/v1/',
'headers': {'Authorization': 'JWT ' + AuthenticationStore.state.token}
})
api.interceptors.request.use(function (config) {
config.headers = {
'Authorization': AuthenticationStore.state.token ? 'Bearer ' + AuthenticationStore.state.token : ''
}
return config
}, function (error) {
// Do something with request error
return Promise.reject(error)
})
export default api
If you need to have no auth header, you need to add if at the begging of the interceptor.
Issue with your store:
You are exporting function when you should export instance of store,
so this is wrong:
const AuthenticationStore = () => {
You should export instance so:
const AuthenticationStore = new Vuex.Store({ ...
Please visit https://vuex.vuejs.org/guide/ to get better understanding. It is not bad that you don't understand it fully! Modules/instances/exporting in JS is not really easy to understand fully. Just try to learn it more. Good luck.

axios set headers in config vue js

Right now I use axios like this:
import axios from 'axios'
axios.get(apiObjUrl,
{
headers: {
'Content-type': 'application/x-www-form-urlencoded',
}
})
.then(({data}) => {
How do I set global axios header?
(I need to set localization header to use in all my requests)
Use an Axios interceptor: https://github.com/mzabriskie/axios#interceptors
In config you have the request's headers.