following the explanation on separating frontend and gateway, I created two JHipster applications:
Gateway using jhipster --skip-client
Frontend using jhipster --skip-server --db --auth uaa --uaa-base-name uaa-server
When using Swagger-UI, I can use the default API and the API of my UAA server. I can also see in the drop-down menu my micro-services but when selecting them, I get an error message :
Can't read swagger JSON from http://127.0.0.1:9000/myservice/v2/api-docs
What is wrong in my configuration ? What did I forget ?
[EDIT] I finally found, see below
The second question is about the communication between frontend and gateway when both are running on different machines.
Authentication seems to be correct when looking at UAA server but frontend side receives a 403 code. It seems to be a problem with CSRF but I don't know how to handle it.
What's the way to deal with CSRF in JHipster ?
PS : I'm pretty sure I will also have problem when making to microservices talk together :)
Added contexts for proxying in webpack.dev.js and it seems to be working.
Related
first of all I am new to Jhipster. I have created jhipster gateway (Frontend) with angular without application (backend).
I was expecting that this will not work as backend is not present/working and all service calls will go through backend to access db.
When I am trying to access frontend using http://localhost:8080, I can see everthing is working. I am not sure how. can someone explain?
JHipster v6.10.5 is used for this.
Thanks
Shirish
Application responses for JHispter commandline:
? Which *type* of application would you like to create? Microservice gateway
? [Beta] Do you want to make it reactive with Spring WebFlux? No
? What is the base name of your application? gateway
? As you are running in a microservice architecture, on which port would like your server to run? It should be unique to avoid port conflicts. 8080
? What is your default Java package name? com.btn.test
? Which service discovery server do you want to use? JHipster Registry (uses Eureka, provides Spring Cloud Config support and monitoring dashboards)
? Which *type* of authentication would you like to use? JWT authentication (stateless, with a token)
? Which *type* of database would you like to use? SQL (H2, MySQL, MariaDB, PostgreSQL, Oracle, MSSQL)
? Which *production* database would you like to use? MySQL ? Which *development* database would you like to use? MySQL
? Do you want to use the Spring cache abstraction? Yes, with the Hazelcast implementation (distributed cache, for multiple nodes, supports rate-limiting for gateway applications)
? Do you want to use Hibernate 2nd level cache? Yes
? Would you like to use Maven or Gradle for building the backend? Maven
? Which other technologies would you like to use?
? Which *Framework* would you like to use for the client? Angular
? Would you like to use a Bootswatch theme (https://bootswatch.com/)? Default JHipster
? Would you like to enable internationalization support? No
? Besides JUnit and Jest, which testing frameworks would you like to use? Gatling, Cucumber, Protractor
? Would you like to install other generators from the JHipster Marketplace? (y/N) No
emp.jdl
/**
* The Employee entity.
* #author Shirish Bathe
*/
entity Employee {
name String required unique
dept String
}
Now I have access gateway using http://localhost:8080 and tried to access employee entity. I am able to see (fake) data in a table.
Hence Even if backend application is not present, application is working fine. how? Am I missing anything?
The gateway contains the whole UI. The microservices come into play when you define entities. These are not managed by the gateway (but the UI is). This overview pictures describes the architecture quite well:
https://www.jhipster.tech/microservices-architecture/
Using jhipster 5.7.2
I created an api-gateway, and two micro-services.
In the first one, I created an entity and it works perfectly behind the gateway. The gateway displays the api endpoints for the generated entity.
I generated the second micro-service but this time I had already an api defined in a yml file so I chose 'API-first'.
My api was defined using open-api 3.
I successfully generated the code for my api, using the instructions there, and tested calling direcly my micro-service endpoint using curl : it worked as expected at this point.
The problem : when I put that micro-service behind the gateway, the gateway does not see the api. When I go to the api menu, my micro-service shows in the dropdown but when I select it, it shows no endpoints.
One weird thing I found while searching is that when I call the following url on my micro-service directly : http://localhost:8082/v2/api-docs (as pointed in the 'welcome page' of the micro-service), I get :
{"swagger":"2.0","info":{"description":"my micro-service API documentation","version":"0.0.1","title":"api-first micro-service API","contact":{},"license":{}},"host":"localhost:8082","basePath":"/"}
It says 'swagger 2.0' when my yml file declared openapi 3.0.1.
I searched and found this issue, which says :
Swagger UI very old version (2.2.10) is used which does not provide
the support for Open API
I though openapi was the problem, so I rewrote the yml file to swagger 2.0 and finally I have the same exact problem : micro-service API works but seems not visible to the gateway.
I'm starting to wonder if it's a problem on my side only.
By default, JHipster configures Swagger to only list API endpoints beginning with api. This is configured in application.yml, change default-include-pattern to include other paths. For example, to include endpoints beginning with either /api/ or /expires/, you can use the following:
swagger:
default-include-pattern: /(api|expires)/.*
So I built an app I wanted with all blows and whistles including integration with OpenID Connect (OIDC "oidc-client").
Problem is it works only at DEV environment, since electron spins local server for it, so when I'm redirected after identification my app in DEV mode listense to "localhost:3000" and oidc-client can proceed with saving token and other things.
But, once I have built a production version, electron serves react as a static files, so all URL are now "file://....", and once I'm redirected after identification this time, no one is there to listen at OIDC callback at "localhost:3000". I drilled the docs of electron and OIDC but haven't found even one example on how to implement this case.
Anyone have successfully "listened" to callbacks at production version in Electron? The only option I have in mind is to spin up a server at prod and listen to "localhost:3000", but than the question is where to redirect it, so OIDC will catch it? I'll appreciate any input, thank you in advance.
Here some visual explanation of what I described.
Hmm - how are you packaging the app? I have a couple of Electron samples you could compare against, both of which you can run pretty easily against my cloud API and Authorization Server:
Loopback Sample using Plain Typescript
Private URI Scheme using React + Webpack
In both cases I can run a packaged app via 'npm run pack'. In my case I am using electron-packager to build release binaries.
I use AppAuth-JS and here is my code to listen on a loopback URL.
Not sure I fully understand your problem, but hopefully it gives you a few pointers.
I am currently working on a small project where I used vue.js to build the front end and express.js for the backend.
For the frontend, I have another express server to just serve the static files and all the requests will be redirected to my backend API with proxy by the frontend server.
For the backend, it is just an Express API app.
Both apps are runing on heroku right now. And my questions is:
What is the best practice to connect the front end and back end server, I did a lot of research online and people are saying backend API are not supposed to be exposed to internet? I am not sure how I can talk to my backend if it is not on internet.
For the frontend, I can use SSL/TLS to protect the connection. But for frontend to backend server communication, what should I do to protect this data transfer, can I use another SSL/TLS? And should I use some mechanism to verify that the request is sent from my frontend server, not somewhere else? If so, what is the recommanded way to do that?
A lot people say that there should not be direct connection with database, it should go through a web service for security. What does that means? Now in my backend Express app, I have line of mongoose.connect('mongodb://someaddress/myapp'); Is this bad practice? If so, what should I do to make it more secure?
Please try to be more specific, I am still new to theses and try to learn, code examples can really help. Much appreciated!!
Vue and Express apps are written in the same language, so it is best practice to have these as separate projects as you have done. These are entirely different projects doing different things so they should be split.
You already deployed to Heroku, so the SSL/TLS isn't really a concern for you. However if you were deploying to your own VPS, you'd want something like Let's Encrypt. For restricting requests from Express to your Vue app, you'll want to look into CORS. See expressjs/cors for more details.
The Express app is the service connecting to your database. If you were trying to directly connect to your database from your Vue app, then that becomes an issue. You would coupling client side code with server side code. What you're doing is fine.
I'm trying to understand how a MERN app fully works, I've been reading about MongoDB, ExpressJs, ReactJs and NodeJs, I also understand how MongoDB, ExpressJs and NodeJs interact and how ReactJs works on its own, my question is simple (I think).
The question:
If I create an API, using Node,Express and Mongo, and I have an APP managed by React, both need a server (via express, I understand), then, how should I run the API and the React app at the same time. Do I need different URLs? should I configure different ports? how should I integrate them?
I really been reading a lot, but almost every tutorial is made locally (and I'm working in a server with Passenger and I can't change the way it starts), just for Node/Express(with pug or else)/Mongo or just React, and I don't understand how to connect the API and React.
Thanks
It depends on several factors: environment (e.g. development, production), and your control over the server. For development, you can have two different URLs and use something like Webpack Dev Server. Normally you would have the module bundler, e.g. Webpack, watching for changes in your React code. However, this can get more complex if you have Server Side Rendering.
For production, normally you would have the bundled file for your client side application already optimized and minified. If you can change your API, you could serve it statically in a new endpoint, for example: /static/bundle.js and request this endpoint from your index.html file, which will be sent by Express.js server when accessing /.
However, because you will probably want to have routes in your React app, your server will need to know how to handle the client app routes (for example app.get('/*', () => ...), and they could collide with your API endpoints. To solve this, you could:
Prefix your API endpoints with a namespace, e.g. /api/v1/...
Place the API in a different URL, port or subdomain. In this case you would indeed need to run these two servers in parallel. With Node.js, there are helpers to make this more convenient, e.g. concurrently.
Pulling out your concerns: API, React, and Integration for MERN app.
I use three approaches
1) Use foreman. With this, you can specify your API and Web Client in the Procfile. I used it here
2) Use a proxy to handle requests that require your API. So in package.json, you specify your API URL(your API must be running)
// package.json
.......
.......
"proxy": "<path to url:[port no if you're developing locally]>"
Check here.
And you can simply add a script to run your API and React concurrently.
3) Set your API and React app in a Docker container. mern-starter is a perfect place to check for this.
Hope this helps!