I developed an Angular app for a manufacturer that allows their customers to place orders for their products. The app uses a web service that is made available by the manufacturer's software, so it mainly consists of an Angular frontend + a PHP backend that mostly acts as a bridge between the frontend and the web service.
I've been contacted by owners of another website that allows users to design products, and they would like to add to their website the possibility of designing a product and sending the order straight to the manufacturer.
Normally I would design a simple backend API on the manufacturer server and expose the functions that they need. But since the manufacturer app is mostly frontend, I would need to port half of it to PHP just to make the API work. I want to avoid this code duplication so I quickly scratched this idea.
I am thinking about implementing an authentication/authorization mechanism inspired by Paypal, aka opening a popup from the design site to the manufacturer app and placing the order through a dedicated Angular route. I made some research and I'll try to detail below what I've come up with, as I'm concerned with security and I'd love some opinions.
First of all, every communication between the two servers is going to be protected using a JWT based approach with an initial authentication. The Design server will be given a Client ID and a Secret that must be safely stored for this purpose. Non-secure HTTP requests will be denied.
Ideal user workflow
Users must link their Design account to their Manufacture account by clicking on a dedicated link on their Design profile. This opens a popup that allows them to authenticate with their credentials, and authorize the Design website to place orders for them. This removes the need to authenticate for every order they place. An entry is stored in the Manufacturer server binding the Client ID to that particular customer account.
After designing a product on the Design website, users can send the order to the Manufacturer by clicking on a button. This opens a popup to the Manufacturer website targeting a route that receives the order data and places the order. After receiving order confirmation, the popup can be closed. This could potentially be replaced by an iframe but I'm not sure if that compromises security even more (although I'm interested to know).
Order button flow
- The Design page makes an async request to the Design server containing the order data. The design server contacts the Manufacturer server with the data, and asks for authorization.
- The Manufacturer server receives and stores the order data, replying with a short-lived, single-use token that is transmitted back to the Design page.
- Upon receiving the token, the Design page opens a popup, passing the token as an URL parameter.
- The Manufacturer popup asks its backend to check the token validity. If the token is valid, the corresponding order is retrieved from storage and sent to the frontend popup.
- Order is placed, confirmation is shown and the stored order/token pair is deleted from storage.
- Popup is closed and Design page workflow is resumed.
I tried to the best of my knowledge to limit security issues, but I'm definitely no expert so here I am. What worries me is:
- the performance cost of making so many requests for such a simple operation;
- potential security dangers / pitfalls I've overlooked.
I tried to rely mostly on server-side requests for sensitive data (Client Secret and Authorization mostly). I would be interested in a frontend-based solution but I understand it involves a lot more security risks. I tried looking into Paypal APIs for research but it didn't help much.
Finally, an iframe variant is tempting for a better user experience but I'm not really sure about it (never used iframes much).