How to consume Notion API with React - javascript

I'm trying to use the new Notion API as a CMS for my personnal website.
As a way to improve, i tried to use it with React. But it seems that it does not allow CORS (i use Axios).
What is the best way to consume this API ? Use an Express.JS Back-end ? I would think it's overkill for my use (I just want to read pages & blocks, not edit).
Here is my actual API Call, but from React :
const getPages = (apiCmsPage) => {
var config = {
method: 'get',
url: 'https://api.notion.com/v1/blocks/'+ apiCmsPage +'/children?page_size=100',
headers: {
'Authorization': KEY,
'User-Agent' : 'PostmanRuntime/7.26.8'
}
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
}
In fact, I never really experienced back-end, so I don't know if it's really obligated to use the API.
Thanks.

I solved this problem by Next.js.
I tried the official notion-sdk-js, but still can’t solve this problem, because it may be aimed at the server instead of the client.
By using the getServerSideProps of Next.js, Notion data can be obtained through fetch before each client request, and then the rendered page is directly returned to the client. Because the request is completed on the server side, there is no CORS problem. But the price is that you have to keep a Next.js process in the background for rendering the page.

Would you consider using a react framework like NextJS? You can use its SSG feature to generate the pages during build time, in which your credentials will not be visible on client side.
https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation
Notion also has an official js sdk, so you don't have to do all the API call hard work:
https://github.com/makenotion/notion-sdk-js

Related

Accessing Azure Application Settings with JavaScript

I am hosting my website with Microsoft Azure. I have set up a few Application Settings (which should act as Environment Variables) for a secret key and ClientID for some GET requests I am doing. I have spent the last 3 hours googling trying to find a solution. According to Azure's Docs, I need to use process.env.KEY, but that is not working. When that is done I get this error in the console of my website jQuery.Deferred exception: process is not defined ReferenceError: process is not defined
Everything that I have so found is Node.js, but I do not use that. My website is purely HTML, CSS and the occational JavaScript script. Anyone that has any answers for me that can either put me on the correct path or helps me solve the issue completely?
Edit: This is the code for my script.js
$(document).ready(function() {
// $(window).scroll(function(){
// if(this.scrollY > 20){
// $(".menu").addClass("sticky");
// }
// else {
// $(".menu").removeClass("sticky");
// }
// });
$('.menu-toggler').click(function() {
$(this).toggleClass("active");
$(".menu-menu").toggleClass("active");
});
// Check if streamer is live on twitch
const Url = 'https://api.twitch.tv/helix/streams?user_login=pokimane';
$.ajax({
url: Url,
type: "GET",
success: function(result) {
var json = JSON.stringify(result);
if (json.includes('"type":')) {
$(".twitch").addClass("live");
};
},
error: function(error) {
console.log(`Error ${error}`)
},
isLocal: true,
jsonp: true,
headers: {
'Client-ID': process.env.CLIENT_ID,
'Authorization': `Bearer ${process.env.CLIENT_AUTH}`,
'accept': 'application/vnd.twitchtv.v5+json',
}
});
});
NEWEST
This api need add bear token to request.
According to your description, your project is only html+js, which is originally a static resource, hard coding will definitely cause security issues. But you will be much safer using rest api now.
Because you first need to obtain the bear token, you need to refer to the official documentation for details.
Microsoft identity platform and OAuth 2.0 authorization code flow
If you want to make minimal changes to the project, you may need to use ROPC flow. You can refer my another in another post.
PRIVIOUS
You can use rest api to get application settings.
The JavaScript script in Html does not support node usage. The syntax of process.env.CLIENT_ID is suitable for use in complete nodejs projects. It is recommended to use restapi to get the value of the application settings you want.
My custom settings in portal.
You can access this site. Web Apps - List Application Settings.

Front-end JS and the lack of http/authentication management

Last days I was developing an http manager for the front of an app, with a part of authentication. For the context this app is made with Typescript, React-redux, and a back with Java/Springboot.
I wanted to :
link the typing of the request with the typing of the data returned by the server, like that:
request({
type: 'login',
parameters: {
username,
password
}
}).then(response => {
typeof response.data;
// for the request type 'login'
// the data returned is { token: string }
})
handle the authentication, requests that need it
handle CRUD requests with simplicity
The problem, I have to do all the work myself. I didn't found any library that help me.
I use Axios but it's not a manager like i imagine.
I know there is an Angular module, HttpClient i think, that seems to respect my need, but it's by definition Angular-oriented. I found RxJS making reactive requests with observables, but I don't think it's what i'm searching.
It's a problematic I encounter pretty often, http requests and authentication are common of most of the web apps. It's obvious that every front dev know this problem.
NodeJS has Passport.js, Java has Spring, etc
What do we have in the front-end ?

Making POST request from ReactJS app built on WordPress

I'm building a ReactJS app on top of a WordPress backend. The React App is running on the same domain, embedded in the WordPress site. Most of the tutorials I've been following cover how to get data from WordPress to React. I've been successful at this, but need to figure out how to submit data from my React app to WordPress (preferably via the REST API).
This will be a custom admin page for logged in editors, either available in the admin panel or from the front-end.
As an example to create a post, I'm naively trying the following function:
saveGrid() {
const url = "/wp-json/wp/v2/posts";
const body = JSON.stringify({
"title":"internet",
"content":"teapot"
});
fetch(url, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body:body
});
}
I get back a 401 unauthorized response. What is the easiest way to authorize myself for a POST submission (secure solution preferred)?
It looks like you're on the right track.
A quick read of this: https://apppresser.com/wp-api-post-submission/
shows me that all you're missing is a "nonce" in order for the WP API to recognise and validate your request successfully.
In the guide above, the dev created a JS written in JQuery that sends XHR/AJAX requests to the WP API and in their plugin.php they enqueue and localize the script with some variables from WP to help with the request inside the JS.
The takeaway here is that they used wp_create_nonce('wp_rest')and assigned this to a localized variable nonce so they could easily reference that later inside the JS and assign nonce to their X-WP-Nonce header inside the request!
If you look into this further you might find a suitable alternative for you that will work as I'm not entirely sure how you're loading your JSX files but this guide may come in handy for you to enqueue your JSX scripts/files: http://blog.milandinic.com/2015/12/01/using-react-jsx-in-wordpress/
More information
https://codex.wordpress.org/Function_Reference/wp_localize_script
https://developer.wordpress.org/reference/functions/wp_enqueue_script/
I was able to solve this problem by, instead of having a straight post request from React, using a Jquery AJAX submission outside of React that uses data from a form inside React. This caused the request to contain the necessary cookies (I don't understand exactly why this is the case)

Rest API and Axios Request

I've written this code:
doIt(evt) {
axios.get('/book', {
params: {
id: 1
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
I want to get the book with id = 1
I'm using a server running in nginx.
I don't know how to receive this request in the server and how to send the response to my client.
Help me please.
When you have a JavaScript front end that consumes a REST API back end, you have programming logic at both ends.
On its own, nginx is typically used for server static files or reverse proxying - it doesn't have its own way of serving a REST API.
You would typically use a web framework with a database to do the back end logic of serving the API. One example of this is Django with Django REST framework.
Here is an example of how you might set up such a back end stack. Many other web frameworks are available that can be set up with nginx and do a similar job.

How to Call a Firebase Authenticated Cloud Endpoint from Javascript?

I've written several Google Cloud Endpoints in Python and have followed the directions to require that calls to them come from users authenticated using Firebase. I need to call my Endpoints from a web app using JavaScript, but I can't seem to get the authentication working.
I'd like to use the Google APIs client (gapi) which comes with the added benefit of dynamically generating the client library from a provided discovery document. When I try using the gapi client, I can make the call to my API just fine, but I get an HTTP 401 as a response, along with the HTTP unauthorized message that my python source returns.
Google's documentation on the subject is rather sparse. I gather from one tutorial on the subject that a standard Ajax call can be used, but I don't see any documentation on how to call a Firebase authenticated endpoint from Gapi. My current concern is that the gapi client may not be set up (yet) to allow for the use of a discovery doc and also allow for the Authorization header to be set as Firebase Auth requires.
Is what I'm attempting even possible?
Any suggestions would be appreciated. Perhaps calling a Firebase Authenticated endpoint isn't possible using the gapi client.
Here's a rough outline of my gapi js code:
function(token) {
gapi.client.init({
apiKey: 'MY_API_KEY',
discoveryDocs: [MY_DISCOVERY_DOC_URL'],
clientId: 'MY_WEB_CLIENT_ID',
scope: 'profile'
}).then(function(){
return gapi.client.my.server.api.call();
}).then(function(response){
console.log(response.result.data)
}, function(reason){
console.log('Error: ' + reason.result.error.message)
});
}
I have been struggling with this for a while now and finally made it work. I found two options:
Option 1) If you want to use the gapi.client library:
There is a method called gapi.client.setToken(tokenObject) - documentation
However, it seems to be new (July '17) and little documentation or examples are available. I made it work doing the following (this is in angularJS with angular-fire but I hope you get what I am doing, basically ignore the "$scope")
// any time auth state changes, add the user data to scope
$scope.auth.$onAuthStateChanged(function (firebaseUser) {
$scope.firebaseUser = firebaseUser;
$scope.idToken = null;
// get the token from the firebase User Object
// Note that getToken() is deprecated and for me it did not work as desired
// use getIdToken() instead
firebaseUser.getIdToken().then(function (idToken) {
$scope.idToken = idToken;
});
});
// Now you can use setToken
// If from the docs you were thinking firebase's getIdToken() gives me TokenObject and gapi's setToken()
// expects a TokenObject so I'll just pass it - you'd be wrong! (at least for me - if it works for you please give me a heads up)
// You'll need to build your own token:
var homemadeToken = {
access_token: $scope.idToken.toString() // This feels so wrong
};
gapi.client.setToken(homemadeToken);
gapi.client.yourapi.getSomething().execute(function (resp) {
// Do stuff with the response
}
);
Option 2) Use jQuery's Ajax request - documentation
$.ajax(backendHostUrl + '/_ah/api/yourapi/v1/someendpoint', {
headers: {
'Authorization': 'Bearer ' + $scope.idToken // Here it worked without making a string first but I did not check why
},
method: 'GET',
success: function (resp) {
// Do stuff with the response
}
});
If after all of that your backend is still not accepting the tokens and you have migrated from endpoints v1 to v2, it might help migrating again as described here. Esp. make sure the lib folder is created again.
Even after SDK updates, I noticed that if and once you migrated from v1 to v2 the "lib" folder is never updated regardless of whether or not it hase been updated.
Still not working?
This github page fixes the issue on the BACKEND side for an earlier version - the backend did not accept firebase tokens and needed to be hacked. If you want to apply the changes as described there and you are using the latest "lib" folder's (writing in July '17) users_id_token.py as per migration guide, note that the file has changed and you need to go against the explicit commentary in that file's _verify_signed_jwt_with_certs method:
# Formerly we would parse the token body here.
# However, it's not safe to do that without first checking the signature.
and parse the token before checking the signature. From that file's comments it can be inferred however, that Google plans to put the entire logic elsewhere - hopefully firebase friendly and safely.

Categories

Resources