Get Nuxt inject API alias outside *vue file - vue.js

As the way of injecting API and call API by nuxt alias like this post
NuxtJS - manage several axios instances
It is working well with Vue file or middleware.
But since I create new folder in src is service for managing API, I can't call alias of API any more.
-src
-plugins
-api.js
-services
-user.js
in file user.js, I use alias to call API but it does not work ($nuxt.$api)
user.js
export default {
async getUser(payload) {
return await $nuxt.$api.get('/user/', {
headers: {
Authorization: `Bearer ${payload}`
}
})
}
}
How can I solve my issue?

Related

Protect api routes with middleware in nextJS?

I'm new to next.js and I wanted to know if I could protect a whole API route via middleware. So for example if i wanted to protect /api/users Could I create /api/users/_middleware.ts and handle authentication in the middleware and not have to worry about authentication in the actual api endpoints? If so, how would I go about doing that? The library i'm using right now is #auth0\nextjs-auth0 so I guess it would look something like this? (Also please forgive me if I code this wrong, I am doing this in the stackoverflow editor)
export default authMiddleware(req,res)=>{
const {user,error,isLoading} = whateverTheNameOfTheAuth0HookIs()
if(user)
{
// Allow the request to the api route
}
else
{
// Deny the request with HTTP 401
}
}
Do I have the general idea correct?
next-auth v4 introduced middleware for this purpose. The basic use case is pretty simple.
You can add a middleware.js file with the following:
export { default } from "next-auth/middleware"
export const config = { matcher: ["/dashboard"] }
Other use cases can be found in the documentation
You can use middleware for that, something similar to this example from the documentation.
For a sub-directory inside pages, you can create a _middleware.ts file. It will run for all pages in this directory. It looks something like this:
import { NextRequest, NextResponse } from 'next/server'
export function middleware(req: NextRequest) {
const basicAuth = req.headers.get('authorization')
if (basicAuth) {
// do whatever checks you need here
const hasAccess = ...
if (hasAccess) {
// will render the specified page
return NextResponse.next()
}
}
// will not allow access
return new Response('No access', {
status: 401,
headers: {
'WWW-Authenticate': 'Basic realm="Secure Area"',
},
})
}
You can find more info in the documentation.

Shopify node backend- frontend communication

I am really new in shopify app development.
I have an allready a working app what i have created with next.JS (I have worked with node/express too)
I just would like to create a connection between my frontend and backend with a simple endpoint.
It means i send a get request and i receive something nonsense. The main goal would be that is the backend can communicate with the frontend.
I have created a git repo too.: https://github.com/akospaska/shopify-outofthebox
The app has been created with shopify-cli
In my pages folder there is an index.js file, where my frontend "lives". 
I have created (or i think ) 2 differend endpoints.
pages/api/test   endpoint: "/test"
server/server.js  endpoint: "/test2"
When i call the endpoints i get an error. 
I have read the documentation but it just makes me confused.
How should i authenticate between my backend and frontend exactly?
Thank you for your help Guys in advance.
The endpoints aren't pages, they are routes on your express app.
Here is a related question with answer:
Node backend communication between react frontend and node backend | Shopify related
Here is a checklist for you how to set up an endpoint (POST):
1.) Navigate to your index.js file in the /web directory
2.) Insert this code:
app.post("/api/test", async (req, res) => {
try {
res.status(201).send(response);
} catch (error) {
res.status(500).send(error.message);
}
});
}
app.post() sets up a route in your project.
3.) Navigate to your index.jsx file in /pages directory and insert this code (I set up a callback when a form submit button is clicked):
const handleSubmit = useCallback(
(body) => {
(async () => {
const parsedBody = body;
const response = await fetch("/api/test?shop=YOUR_SHOP_URL, {
method: "POST",
body: parsedBody
});
if (response.ok) {
console.log("Success");
}
})();
return { status: "success" };
},
[]
);
<Form onSubmit={handleSubmit}>
</Form>
it should call this API endpoint. So now you communicate with an API endpoint.
Maybe I could help you with my answer!

Forward basiauth to axios

I have a site which makes an Axios request. Both the backend and vuejs frontend are on the same domain, and have the same basic auth covering them.
The issue is that whilst the pages load, as soon as an Axios request is made, it asks me again for the basic auth, which doesn't even work if I fill in the details.
Now I imagine I need to pass through the basic auth details somehow, but none of the things I have tried work (and example being below).
If anyone has any tips on passing through the auth token from the parent page to the axios request, that would be great.
const requestOne = axios.get(requestUrl)
const requestTwo = axios.get(requestUrl)
axios
.all([requestOne, requestTwo])
.then(
axios.spread((...responses) => {
<some code here>
})
)
I just answered a similar question with the 3 ways to pass around data in Vue.
You might find it helpful: How to pass v-for index to other components
However, in my opinion, the best approach would be to create a Vue plugin with your Axios client and an init method.
Consider this following (untested) example:
axiosClient.js
import Vue from 'vue';
let instance;
export const getInstance = () => instance;
export const useAxios = () => {
if (instance) return instance;
instance = new Vue({
data() {
return {
client: null,
}
}
});
methods: {
init(authToken) {
this.client = axios.create({
headers: {'Authorization': authToken }
});
}
}
}
export const axiosPlugin = {
install(Vue) {
Vue.prototype.$axios = useAxios();
},
};
Vue.use(axiosPlugin);
Once installed, you can access this in your components using $axios.init(...) and $axios.client.
You can even write API methods directly onto the plugin as well and interact with Vuex through the plugin!
You may need to tweak the plugin a little (and keep in mind this is Vue2 syntax) as I wrote this directly into StackOverflow.
You can also pass any other default values or configuration options through to the axios client by providing options to the plugin and accessing them within init.
You can learn more about plugins here: https://v2.vuejs.org/v2/guide/plugins.html

Feedly API with NuxtJS Axios

I am trying to access the Feedly API via my nuxtjs site. To do so, I am using the nuxt-axios module.
To get started, I take note of the Feedly API instructions:
We offer a standard OAuth 2.0 authentication module which provide the application an OAuth access token. Most endpoints expect an Authorization header.
$ curl -H 'Authorization: OAuth [your developer access token]' https://cloud.feedly.com/v3/profile
I now attempt to integrate this into nuxtjs-axios.
First, I set up my nuxt-config.js file:
export default {
...
plugins: [{ src: `~/plugins/axios.js` }],
modules: [
'#nuxtjs/axios',
],
axios: {
credentials: true
},
env: {
FEEDLY_ACCESS_TOKEN:
[MY_FEEDLY_DEV_ACCESS_TOKEN]
},
...
}
I then create a axios.js plugin in the plugins folder (which is imported into the nuxt-config.js file that I noted above):
export default function({ $axios }) {
$axios.setHeader('Authorization', `OAuth ${process.env.FEEDLY_ACCESS_TOKEN}`)
}
The problem is that I have no idea what I'm supposed to put in the axios.js plugin file --- or even if that is the right way to do this. What I did is really just a stab in the dark.
So my question is, how can I implement the Feedly API into nuxtjs using the nuxtjs-axios module?
Thanks.
Use interceptor:
// Add a request interceptor
axios.interceptors.request.use(function (config) {
// Do something before request is sent
return config;
}, function (error) {
// Do something with request error
return Promise.reject(error);
});
// Add a response interceptor
axios.interceptors.response.use(function (response) {
// Any status code that lie within the range of 2xx cause this function to trigger
// Do something with response data
return response;
}, function (error) {
// Any status codes that falls outside the range of 2xx cause this function to trigger
// Do something with response error
return Promise.reject(error);
});
https://github.com/axios/axios/blob/master/README.md#interceptors
What I've understood of the nuxt-axios documentation is that the plugin.axios file is used for adding "default" behavior (axios helpers: https://axios.nuxtjs.org/helpers/)
I think that you've got the plugin right (if the token is the only thing you need to add to your header).
With the nuxt-axios enabled you can now use the this.$axios.get/post.
Have you tried to run a component with:
this.$axios.get('**feedly_url_api_url_here**').then(response)....

Vue.js environment variables not working with axios on Heroku

I have deployed a Vue.js application to heroku an api also hosted on heroku.
The VueJS app uses axios to connect to the api. I have set a config variable in heroku:
VUE_APP_ROOT_API = https://[my-express-api].herokuapp.com/api
Here is my base axios call:
import axios from 'axios'
const token = localStorage.getItem('token')
export default () => {
console.log(process.env.VUE_APP_ROOT_API)
return axios.create({
baseURL: process.env.VUE_APP_ROOT_API,
headers: {
'Content-Type': 'application/json',
token: token,
},
validateStatus: function () {
return true;
}
})
}
However, the console log reveals that the variable is undefined and axios is using the Vue app url as the base for api calls (https://[my-vue-app].herokuapp.com/undefined/) instead of the one specified in the config variable.
Resolved this. It turns out that my config variable was being compiled into the code at build time, so once I deployed to trigger a rebuild, the new config var worked. Adding/Updating config vars will automatically restart the dynos, but that doesn't rebuild any compiled code.
For me, appending the build command in my package.json with '--mode production' before pushing to heroku fixed the issue.
https://forum.vuejs.org/t/production-env-on-app-deployed-in-heroku/71077
Good luck!