Sending data from frontend to backend in shopify - javascript

I'm developing an app with node and react. In this app, I have created a scriptTag using the fetch function to get customer id and product id whenever a specific button is pressed. Now when I have fetched that data, I want to store it in my firebase database, which I cannot import in my script tag file because it's on the front end. Therefore, I need to send the data from my frontend to the backend of the app but I'm confused that if I use the fetch function to make POST and GET requests, what URL should I use? Moreover, can the fetch function even post the variable values or not?
Scripttag.js
const header = $('header.site-header').parent();
header.prepend('<div>Hello this is coming from the public folder </div>').css({'background-color':'orange', 'text-align': 'center'})
function addWishList(customer, productid){
/*
fetch(`url`, {
method: 'POST',
headers: {
'Content-Type': ,
"X-Shopify-Access-Token": ,
},
body:
}})
})
*/
console.log('adding item to the wishlist!!')
}
function removeWishList(){
console.log('removing item from the wishlist!!')
}
var wishbtn = document.querySelector('.wishlist-btn')
wishbtn.addEventListener('click', function(){
if(this.classList.contains('active')){ //condition to check if the button is already pressed
removeWishList();
this.classList.remove('active');
this.innerHTML = 'Add to wishlist'
}
else{
var customer = wishbtn.dataset.customer;
if(customer == null || customer == ''){
console.log('Please log in to add this item to your wishlist')
}
else{
var productid = wishbtn.dataset.product;
this.classList.add('active'); //when the user presses add to wishlist button, it add active to the button's class
this.innerHTML = 'Remove from wishlist'
addWishList(customer, productid);
}
}
})

The best way to send data from the frontend to the backend is to use the Proxy option that is provided in the Shopify Partner Dashboard.
This way you can stay in the Shopify environment since it will pass specific arguments to the request that you can check if the request is truly coming from Shopify and you will have one less worry about securing it from outside requests.
So for example you will make a fetch request to /apps/YOUR_CUSTOM_PATH and this will proxy to your URL https://example.com/custom_path where you will handle the request.
You can see more info here: https://shopify.dev/tutorials/display-data-on-an-online-store-with-an-application-proxy-app-extension
You can create a public route for your app as well that can be requested from everywhere and allow for CORS but it's usually more work to do so... so pick your poison.
Have in mind that when creating a proxy page you need to reinstall the app on the store to take effect.
PS: Don't ever use the Access Token in the frontend, that should be never present in the frontend. The AccessToken is only back-end way of communicating with the API!

Related

Express redirect user and send data along with it to be accessed by angular 8 client

The scenario is payment gateway post some payment data to url '/payment-check'. On successful verification, I redirect the user to a particular url and set the header to be accessed by the angular client later.
Now the problem is headers are set in the post method and from angular, I can't make post method because payment gateway is posting data.
I also don't have payment data in the get method(express server) to send to the angular client.
Now how can I get set headers(payment data) in angular?
Or is there any alternative / easier way to achieve it.
One of the ways to do is querystring. But as payment_data is sensitive it is not a good idea to expose it in url
Here is my code
express.js file
router.post('/payment-check', function(req,res ) {
var options = req.body
console.log(options)
let secret ='XXXXXXXXX'
console.log(options.razorpay_order_id + "|" + options.razorpay_payment_id, secret)
if(// verification code) {
console.log("matched")
var payment_id = options.razorpay_payment_id
res.setHeader('payment_id' ,payment_id)
res.redirect('http://localhost:8100/menu/items/carts/payment-options/netbanking/order-success')
}
})
angular service
getPayemnt_id(): Observable<any> {
return this.http.get<any>(this.url + 'payment-check')
}
.ts page
this.serivename.getPayemnt_id().subscribe(data =>{
console.log(data)
})

how can i use laravel csrf token on my nuxt vps

I started creating a new application using Laravel and Nuxt Js.
i have two VPS servers :
The first one contain my Nuxt JS ( Front End )
The second one is the end point ( back end ) based on Laravel
i have created a lot of pages i insert the data correctly into my database. and now i tried to create a new function to update users data, but i get an error after submiting the form since i use the same axios code to insert.
Right now i'm working without tokens and i know its insecure way.
i would like to know how can i communicate the tokens between Nuxt JS front end Laravel Backend.
i have two servers.
the error that i get is :
CSRF token mismatch.", exception: "Symfony\Component\HttpKernel\Exception\HttpException
this is my Axios code :
edit (customerId, submit = false) {
this.editMode = true
this.customerId = customerId
if (submit === 1) {
const formData = $('#add-customer').serialize()
this.$axios.$post('/customer/update', formData).then((response) => {
this.refresh = true
})
} else {
this.$axios.$get('/customer/edit?customer=' + customerId).then((response) => {
this.formFields = response.data[0]
})
}
}
when i change this line from post to get, it works fine
this.$axios.$post('/customer/update', formData)
I would suggest using a single Redis server for session management,so you have a centralized location. or using a database, for more details check laravel doc
https://laravel.com/docs/6.x/session

serviceworker is it possible to add headers to url request

I have a website which I don't want to make people create accounts. It is a news feed with each news article categorized. I want to allow people to tag the categories they are interested in so that next time they go to the site it only shows news for the categories that are tagged.
I'm saving the tags in an indexedDB which I understand is available in a service worker.
Hence in my service worker I want to "intercept" requests to www.my-url.com, check the indexDB for what categories this person is interested in, and add some headers like 'x-my-customer-header': 'technology,physics,sports' so that my server can respond with a dynamic html of those categories only.
However I'm struggling to get the service worker to properly cache my root response. In my serviceworker.js, I console log every event.request for the onFetch handler. There are no requests that are related to my root url. I'm testing right now on my localhost, but I only see fetch requests to css & js files.
Here is my onFetch:
function onFetch(event) {
console.log('onFetch',event.request.url);
event.request.headers["X-my-custom-header"] = "technology,sports";
event.respondWith(
// try to return untouched request from network first
fetch(event.request).catch(function() {
// if it fails, try to return request from the cache
caches.match(event.request).then(function(response) {
if (response) {
return response;
}
// if not found in cache, return default offline content for navigate requests
if (event.request.mode === 'navigate' ||
(event.request.method === 'GET' && event.request.headers.get('accept').includes('text/html'))) {
return caches.match('/offline.html');
}
})
})
);
}
I'm using rails so there is no index.html that exists to be cached, when a user hits my url, the page is dynamically served from my news#controller.
I'm actually using the gem serviceworker-rails
What am I doing wrong? How can I have my service worker save a root file and intercept the request to add headers? Is this even possible?
Credit here goes to Jeff Posnick for his answer on constructing a new Request. You'll need to respond with a fetch that creates a new Request to which you can add headers:
self.addEventListener('fetch', event => {
event.respondWith(customHeaderRequestFetch(event))
})
function customHeaderRequestFetch(event) {
// decide for yourself which values you provide to mode and credentials
// Copy existing headers
const headers = new Headers(event.request.headers);
// Set a new header
headers.set('x-my-custom-header', 'The Most Amazing Header Ever');
// Delete a header
headers.delete('x-request');
const newRequest = new Request(event.request, {
mode: 'cors',
credentials: 'omit',
headers: headers
})
return fetch(newRequest)
}

Access Meteor.userId from outside a method/publish

I'm currently writing a server-centric package for Meteor, and the relevant code looks something like this:
__meteor_bootstrap__.app.stack.unshift({
route: route_final,
handle: function (req,res, next) {
res.writeHead(200, {'Content-Type': 'text/json'});
res.end("Print current user here");
return;
}.future ()
});
This is obviously a relatively hacky way of doing things, but I need to create a RESTful API.
How can I access Meteor.userId() from here? The docs say it can only be accessed from inside a method or publish. Is there any way around that?
Things I've tried:
Capture it from a publish using Meteor.publish("user", function() { user = this.userId() });
Get the token + user id from the cookies and authenticate it myself using something like Meteor.users.findOne({_id:userId,"services.resume.loginTokens.token":logintoken});
Create a method called get_user_id and call it from inside my code below.
The thing that you need to target first is that to get something that can identify the user from headers (especially because you want to get the username at a point where no javascript can run).
Meteor stores session data for logins in localStorage, which can only be accessed via javascript. So it can't check who is logged in until the page has loaded and the headers have been passed.
To do this you need to also store the user data as a cookie as well as on localStorage:
client side js - using cookie setCookie and getCookie functions from w3schools.com
Deps.autorun(function() {
if(Accounts.loginServicesConfigured() && Meteor.userId()) {
setCookie("meteor_userid",Meteor.userId(),30);
setCookie("meteor_logintoken",localStorage.getItem("Meteor.loginToken"),30);
}
});
server side route
handle: function (req,res, next) {
//Parse cookies using get_cookies function from : http://stackoverflow.com/questions/3393854/get-and-set-a-single-cookie-with-node-js-http-server
var userId = get_cookies(req)['meteor_usserid'];
var loginToken = get_cookies(req)['meteor_logintoken'];
var user = Meteor.users.findOne({_id:userId, "services.resume.loginTokens.token":loginToken});
var loggedInUser = (user)?user.username : "Not logged in";
res.writeHead(200, {'Content-Type': 'text/json'});
res.end("Print current user here - " + loggedInUser)
return;
}.future ()
The cookie allows the server to check who is logged in before the page is rendered. It is set as soon as the user is logged in, reactively using Deps.autorun
My solution was inspired by the server part of #Akshat's method. Since I'm making a RESTful API, I just pass the userId/loginToken in every time (either as a param, cookie or header).
For anyone interested, I bundled it as a package: https://github.com/gkoberger/meteor-reststop

Send user details (session token) within every AJAX requests (Sencha Touch 2)

i am building a Sencha Touch 2 Application with userspecific datasets.
Architecture of the App:
Sencha Touch App <=====> Java Server backend with REST Services
( many AJAX requests =) )
What i actually have is:
Login the user with username/password
The app gets initialized and the loginform comes into play. After submitting the form as a AJAX request, the server backend checks the userdata and calls the client callback function.
And what i want to do is:
The callback function should
create a cookie with the sessiontoken or
store the sessiontoken within the localstorage (http://docs.sencha.com/touch/2-0/#!/api/Ext.data.proxy.LocalStorage) or
store the sessiontoken within js variable
Okay, shouldn't be the problem.
But how can i achieve the following:
Most of the data is specific for one user and should be returned by the REST service if needed (by clicking on the navigation,...). How can i send the sessiontoken (see above) within every AJAX request - so the server can provide the suitable datasets (assuming the token is valid)?
Send cookies within AJAX requests
I have already read that cookies gets automaticly added to the request if the url is on the same space, right? The Java Server is on the same domain (localhost:8080) but the cookies aren't available - instead of requests on urls like 'app.json'. I thought that cross-domain-requests are really domain specific?
Send paramaters within AJAX requests
Because the cookies aren't avi i thought about the possiblity of 'manually' adding parameters to the ajax requests. The App will contain many AJAX requests and thats why i dont want to add the token manually - i tried to override the requests function of Ext.Ajax but i failed ;-( :
(function() {
var originalRequest = Ext.data.Connection.prototype.request;
Ext.override(Ext.data.Connection, {
request : function(options) {
alert("Do sth... like add params");
return originalRequest.apply(this, options);
}
});
})();
ERROR:
Uncaught Error: [ERROR][Ext.data.Connection#request] No URL specified
I also tried to add a listener
Ext.Ajax.add({
listeners : {
beforerequest : function( conn, options, eOpts ){
alert("Do sth... like add params");
}
}
});
ERROR:
Uncaught TypeError: Object [object Object] has no method 'add'
Any idea about how i can add the token?
Or any better way of handling these case?
Thanks!
Finally i successfully used:
function addAjaxInterceptor(context)
{
Ext.Ajax.on('beforerequest', function(conn, options, eOptions)
{
// add the param to options...
}, context);
}
Executed from the app (=> addAjaxInterceptor(this)).
But the following solution is more suitable for my situation i think:
Ext.Ajax._defaultHeaders = {
// params as json
};
(Cause Ext.Ajax is a singleton object and i dont change the params for every request)

Categories

Resources