Is there a way to handle the payment in the Backend Nodejs? - node.js

I made a website with react and i used "react-paypal-button-v2" package to integrate paypal to my website,
so everything is working well, but Now what i would like to do is to hide the " ClientId " which is one of the properties of react-paypal-button-v2 as below:
<PayPalButton
amount={amount}
currency={currency}
onSuccess={(details, data) => onSuccess(details, data)}
options={{
clientId: "YOUR_CLINET_ID"
}}
/>
because it is not secure to put sensitive data in the front-end as they said in the documentation from react apps documentation, so for that i decided to handle this on the backend and save the ClientId as a variable and use it each time request payment is fired.
so my question is what is the best way to make the payment on the server side?
or if I'm wrong and there is way better than this please tell me.
thank in advance guys.

The Client ID is not sensitive information. It is intended to be used on the client side.
A server integration uses a client ID + secret for API calls. Server integrations are more robust and secure, so if you have the resources and ability to integrate with a backend it's recommended that you do so.
Vanilla JS+backend approach
Create two routes on your server, one for 'Create Order' and one for 'Capture Order', documented here. These routes should return JSON data. The latter one should (on success) store the payment details in your database before it does the return.
Pair those two routes with the following approval flow: https://developer.paypal.com/demo/checkout/#/pattern/server
React specifics
react-paypal-button-v2 is not an official module, try the newer react-paypal-js instead. See the "Docs" tab of the Storybook.

Related

How to implement JWT auth on Loopback REST API?

I´m pretty new at nodejs, so I tried to implement an REST API with the loopback framework to try to simplify a bit the building process. I did correctly the models, also cusomized some endpoints, but, when connecting with the frontend (AngularJS), all the code I find, also the code I know to build, requires an JWT token to do any task that requires authorization/authentication, but it seems that loopback sends an uid2 token when I log in. I searched a lot, in stackoverflow and Github, the nearest thing I found is this (https://github.com/strongloop/loopback/issues/1905#issuecomment-310382322) but the code seems to fail here:
const data = jwt.verify(id, secretKey);
cb(null, {userId: data.id});
Any idea?
In simple words, you need to know who is making the call. If you'd use the default loopback authentication you would see that in the req object there is accessToken property which identifies the user. If you want to use JWT there are plenty of ready modules you could use, eg. loopback-jwt or loopback-jwt-advanced.
In general, what you need to do is to apply a middleware that will be responsible for authorization of your user( I strongly recommend you to get familiar with the middleware term). In simple words, middleware is a layer that your requests are going through and you can modify it's a body or reject the request.
In abstract steps, in your middleware you would have to:
get the token from the request
verify the token
identify the user based on the token
create the loopback AccessToken entity for that given user
put the token in the req.accessToken so now loopback will know who you are and you could use the ACL.
So this is more or less what those extensions are doing.

Best way to handle API calls from frontend

Okay, so atm i have a frontend application built with Nuxt JS using Axios to do requests to my REST API(separate).
If a user does a search on the website the API URL is visible in XMLHttprequests so everyone could use the API if they want to.
What is the best way of making it so that only users that search through my website gets access to the API and people that just directly to the URL gets denied. I suppose using some sort of token system, but what is the best way to do it? JWT? (Users never log in so there is no "authentication")
Thanks!
IMO, you CANNOT block other illegal clients accessing your
backend as you describe that the official client and other illegal have the same knowledge about your backend.
But you can make it harder for illegal clients to accessing your backend through some approach such as POST all requests, special keys in header, 30-minutes-changed token in header and server-side API throttling by client IP.
If the security of the search API is really important, authenticate it by login; if not, just let it go since it is not in your critical path. Let's focus on other important things.
I'm in the same "boat" and my current setup is actually in VueJs but before even come to StackOverflow I developed a way to actually, the frontend calls the server and then the server calls the API, so in the browser, you will only see calls to the server layer that, the only constraint is that the call must come from the same hostname.
backend is handled with expressJs and frontend with VueJs
// protect /api calls to only be originated from 'process.env.API_ALLOW_HOST'
app.use(api.allowOnlySameDomainRequests());
...
const allowHostname = process.env.API_ALLOW_HOST ||'localhost';
exports.api = {
...
allowOnlySameDomainRequests: (req, res, next) => {
if(req.url.startsWith('/api') && req.hostname === allowHostname) {
// an /api call, only if request is the same
return next();
} else if (!req.url.startsWith('/api')) {
// not an /api call
return next();
}
return res.redirect('/error?code=401');
},
...
};
In our case, we use Oauth2 (Google sign through passportJs) to log in the user, I always have a user id that was given by the OAuth2 successful redirect and that user id is passed to the API in a header, together with the apikey... in the server I check for that userid permissions and I allow or not the action to be executed.
But even I was trying to find something better. I've seen several javascript frontend apps using calls to their backend but they use Bearer tokens.
As a curious user, you would see the paths to all the API and how they are composed, but in my case, you only see calls to the expressJs backend, and only there I forward to the real API... I don't know if that's just "more work", but seemed a bit more "secure" to approach the problem this way.

How can I test (integration-testing) with supertest a Node.js server with Passport JS using facebook/google... strategies with OAUTH2?

I have a Node Js application and I'm integration-testing my app with supertest/superagent + nockjs.
I have a problem, because I want to test my login rest apis using supertest to REPLY with a FAKE PROFILE RESPONSE + token for example for facebook/google/github and so on. (I'm not interested in LocalStrategy, because it' very simple)
How can I do that?
I'm trying with GitHub, and I wrote this code (not working) absolutely wrong, probably very stupid without any sense...It was an experiment XD.
nock('https://github.com/login/oauth')
.get('/authorize?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fapi%2Fauth%2Fgithub%2Fcallback&scope=user%3Aemail&client_id=XXXXXXXXXXXXXXXXXXXX')
.reply(302,undefined,
{
location : "http://localhost:3000/api/auth/github/callback?code=ab7f9823f03071209b26"
}
)
.get('http://localhost:3000/api/auth/github/callback?code=ab7f9823f03071209b26')
.reply(200, responseMocked);
PS: probably I made a mistake with url and status, I don't know.
Also, where I should set the connection.sid's cookie ?
How can I fix/rewrite this code to be able to integration-testing my application?
I'm also interested to use passportjs stub/mock, but I want a library supported and well documented.
UPDATE: I fixed the name of the mocked profile object (responseMocked)
Thank you,
Stefano.

Cross domain Sails.js + Socket.io authorization

I'm working in an application which delivers push content to a group of web applications hosted in different domains. I'm using Sails.js and Socket.io, and structured it like this:
The client script, running on each web application's client's browser, is something like:
socket.on('customEvent', function(message){
//do something with message on event trigger
}
And then, in the server, the event 'customEvent' is emitted when needed, and it works (e.g. on the onConnect event: sails.io.emit('customEvent',{message ...}).
But I'm facing a problem when it comes to handle authorization. The first approach I've tried is a cookie-based auth, as explained here (by changing the api/config/sockets.js function authorizeAttemptedSocketConnection), but it isn't a proper solution for production and it isn't supported in browsers with a more restrictive cookie policy (due to their default prohibition to third-party cookies).
My question is: how to implement a proper cross-browser and cross-domain authorization mechanism using sails.js, that can be supported in socket.io's authorization process?
======
More details:
I also tried adding a login with a well-known oauth provider (e.g. facebook), using this example as a base. I've got the Passport session, but I'm still unable to authenticate from the client script (it only works in pages hosted by my node app directly).
A JSONP request to obtain the session might be a solution, but it didn't work well in Safari. Plus I prefer the user to be authenticated in one of the web apps, rather than in my node application directly.
I believe your routes must handle CORS mate. Example:
'/auth/logout': {
controller: 'AuthController',
action: 'logout',
cors: '*'
},
Of course you can specify the list of ip your are accepting (and then replace the '*').
Worth mentionning that you must specify where socket.io has to connect to (front-end JS):
socket = io.connect(API.url);
For any common http GET/PUT/POST/DELETE, please ensure that your ajax envelope goes with the credentials (cookie). For example with angular:
$httpProvider.defaults.withCredentials = true
Let me know how it goes.

nodejs mobile development: how control navigation flow

I am a nodejs newbie and would like to understand the navigation flow when using nodejs to serve mobile applications.
Moible app
index.html
Show all users
Nodejs server snippit
var myData = {
"employees": [
{ "firstName":"John" , "lastName":"Doe" },
{ "firstName":"Anna" , "lastName":"Smith" },
{ "firstName":"Peter" , "lastName":"Jones" }
]
};
res.send(myData);
Question: how do I display this data on another page (users.html)? I've worked with nodejs where I can just render to a specific path and it picks the appropriate Jade file but not sure how to do it since the html / js files are on the phone and not the server.
If you know of an example application I can just look through that code and figure it out.
Thanks for your help.
First of all you need to understand that your node.js is executed on server side, and all it can do - response on requests and do some logic, that stays on the server.
Then there is .html and .js that is sent to your clients (browser), and it is rendered and executed on client-side. This execution and logic is very different, and is focused to provide user interactions and render all sorts of data.
So all you need is be able to 'ask' server for data (request) and then get response, validate it in browser, if it is valid, you can render it using JS.
In order to make your life easier, consider using jQuery.
AJAX - to make requests to server and get response with data.
express.js - web framework for node, helps with routes.
And just generally - go and try things, experiment and it is better to understand whole picture or specific details frist, before you making any decisions.

Resources