I expect you need to use the URL /export-form-submissions/export
in your fetch
, as all plugin routes are added under a prefix consisting of the the plugin name.
Thanks for your response. This has solved my issue, but I can’t seem to call the endpoint without adding auth: false
to the config
. Otherwise I get a 401.
I don’t want to disable the authentication. How do I include authentication to the request?
Instead of raw ‘fetch’, use the helper plugin…
import { getFetchClient } from '@strapi/helper-plugin';
import pluginId from '../../pluginId';
const handleDownload = async () => {
try {
const { get } = getFetchClient();
const response = await get(`/${pluginId}/export`);
// File downloaded successfully - use response.data
} catch (error) {
// Handle error scenario
}
};
The helper plugin will automate adding the necessary bearer token for the user’s admin session. I don’t know how you would acquire that from the strapi instance object but you could always look at the helper plugin code if you prefer to roll your own ‘fetch’.
Hi,
I have an endpoint called /api/groups created with Content-Type-Builder. Doing a axios request without authorization to this endpoint inside my plugin returns me the data because it is open for public. When doing it like the example you mentioned it returns me a 401 unauthorized and logs me out of the strapi application?
This is my call:
import React, { useState, useEffect } from 'react';
import { getFetchClient } from '@strapi/helper-plugin';
import pluginId from '../../pluginId';
const getGroups = async () => {
try {
const { get } = getFetchClient();
const response = await get('/api/groups');
console.log(response.data);
} catch (error) {
// Handle error scenario
}
};
useEffect(() => {
getGroups();
}, []);
Can you or someone help me?
When you use an API endpoint from within a plugin, you are probably using that code from within the Strapi Admin UI - and the user will then be ‘authenticated’. (The point of using the ‘get’ helper is that it adds the bearer authorization automatically.)
When you use an API endpoint from a separate application, you have two options:
-
Add an API token (generated within the Admin UI) as authorization, or
-
Change the API endpoint to not require authorization.
For a collection type you created by means of the Content Builder, the code for the respective API endpoint can be found in ~/src/api
- one folder per content type. To change the auth type for a particular route, you would need to edit the generated file in the routes
folder, and add auth: false
to the corresponding route entry. Look in the Strapi docs for details of how to configure a core router - e.g. for a generated API endpoint. The sample code there will show you exactly how to override the default auth requirement - or any other route config parameters.
Also, you only need the ‘get’ helper inside the Admin UI … For a separate front-end app, simply use Axios or indeed just the Fetch API.
So what you are basically saying is that I need to use axios
because I am doing the request from the Strapi Admin UI and I will be authenticated
because of that. I have set the endpoint /api/groups/
only to authenticated
and changed my code to this:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import pluginId from '../../pluginId';
const getGroups = async () => {
axios.get('http://localhost:1337/api/groups')
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});
};
useEffect(() => {
getGroups();
}, []);
This returns me a 403 Forbidden now. So that won’t work
My mistake … I obviously misinterpreted your question.
You say in your first question that an plain axios request returns the data from your endpoint and that the API endpoint was set up to be ‘public’ (not requiring authorisation). From my experience, the default is the opposite - i.e. API endpoints are not ‘public’ - and that a plain axios request will fail, just as your second example does.
Could you please explain how you made the API endpoint public, for your first question?
And could you perhaps try the ‘get’ helper code from your first question, now that the API endpoint requires authorisation. I suspect it may now work.
I have read this thread and I have it working right now! I have added a custom route inside my /plugin/server/routes/index.js
and added this handler inside my /plugin/server/controllers/my-controller.js
. Inside this handler I make some queries to normally protected strapi endpoints for public.
This new route is protected and with using the getFetchClient()
it returns me the expected response
Thanks for helping!
@jarmo how did you exactly solve it ?
I am having the same issue and same problem:
I am logged-in in the admin ui of Strapi as superadmin.
My plugin is making one api call to /api/data route (which is a normal custom controller under src/api/data)
I get always 401 and logged-out…
const { get } = getFetchClient();
const response = await get('/api/data');
my routes/data.ts is:
export default {
routes: [
{
method: 'GET',
path: '/data',
handler: 'datat.get',
config: {
policies: [],
middlewares: [],
},
},
],
};
Do I need to add some middleware or policy or what should I change to get this working?
I am using exactly what jamo advised but he is not showing how the route was created and what middleware he used
Can you please let me know how to adjust this route
export default {
routes: [
{
method: 'GET',
path: '/data',
handler: 'datat.get',
config: {
policies: [],
middlewares: [],
},
},
],
};
so that it works when called from a logged-in user in admin panel
Okay. Sharing you a solution which I have used to call the Api from the plugin’s route, controller without using middleware.
Calling API from a Admin component **\src\plugins\plugin-name\admin\src\components\componentName\index.js**
)
const response = await request('/plugin-name/route-name', {
method: 'POST',
body: {
prompt: prompt,
}
})
Create a route at this path **\src\plugins\plugin-name\server\routes\index.js**
and add the below code
module.exports = [
{
method: 'POST',
path: '/route-name',
handler: 'controllerName.myFunction',
},
];
Create a controller at this path **\src\plugins\plugin-name\server\controllers\controllerName.js**
and add the below code:
'use strict';
module.exports = ({ strapi }) => ({
async myFunction(ctx) {
// Your logic (Copy your Normal controller function code here)
},
});
I hope this can give you a better idea now
Thanks a lot for the reply Shekhar.
My issue is that I have done exactly that but I get 401 response code and get unauthorized.
The only difference is that I use getFetchClient
in the plugin client side and not request
Maybe the request
function is something else. How do you import it in the react side?
I have created my route in Strapi src/api/data
and can call it fine with “global api token” and with configuration as posted above.
import { request } from ‘@strapi/helper-plugin’;
I tried using request and get same result.
I get 401 response and get logged-out from the admin ui.
I will write again the use case.
I have created one custom Strapi route/api (not inside the plugin) but in Strapi itself
src/api/data
the src/api/data/routes/data.ts
export default {
routes: [
{
method: 'GET',
path: '/data',
handler: 'data.get',
config: {
policies: [],
middlewares: [],
},
},
],
};
src/api/data/controllers/data.ts
export default {
get: async (ctx, next) => {
try {
ctx.body = 'ok';
} catch (err) {
ctx.body = err;
}
},
};
In the frontend I have created a plugin that makes the calls like
const { get } = getFetchClient();
const response = await get('/api/data');
I also used request as you suggested
In both cases I get 401 response code and get logged-out from Strapi admin panel
Ahhh I see it after checking the same as yours. The normal Api call when used is throwing back to the login screen.
Is there any specific requirement of yours for which you are calling the Normal src/api/data/routes/data.ts? If not, then give it a try by following the above solution which I gave you (Add your Route & Controller with code) under your plugin folder and check if that works okay for you.
I see what you mean now!
Thanks Shekhar…
I added the controller inside the plugin and now it has endpoint like pluginId/
and it the call is working.
I still find it weird that I cannot use endpoints under /api/
existing strapi endpoints.
Do you know any way how to call these data or other custom endpoints from the admin ui ? and not get 401 response + loggedout
I need in my use case to also fetch some data in my plugin from the /api/data endpoints not only things under /pluginId/…
Welcome!
Not sure why the issue exists in place. Will start digging up and find the issue once I get free time.
In the mean time, anyone from the viewer has the solution for @kristijorgji then share the feedback.
Thanks
Maybe this helps someone.
I figured out how to have internal routes used by the plugin, and routes that can be called externally.
This is the setup for …/routes/index.js
module.exports = {
admin: {
type: 'admin',
routes: [
{
// this route can be called externally (e.g. postman) through http://localhost:1337/api/{pluginID}/getCurrent with appropriate api token
method: 'GET',
path: '/getAll',
handler: 'myController.getAll',
config: {
policies: []
}
}
]
},
'content-api': {
type: 'content-api',
routes: [
{
// this route can be called by the plugin using request from '@strapi/helper-plugin' through /{pluginID}/getCurrent
method: 'GET',
path: '/getAll',
handler: 'myController.getAll',
config: {
policies: []
// auth: false
}
}
]
}
}
The routes under “content-api’” will show up in the api token creation menu so you can create the token for them.