This project aims to give an opensource lean boilerplate for email based microservice authentication that can be used by both web applications as well as native applications.
Ideally, we suggest both the web apps and native apps to interact with the backend through APIs after the login. (The project aims especially SPAs.)
Following should apply for the whole structure:
- Lean
- Authentication is done with JWT - Jason Web Tokens
- Stateless, API driven
- Microsevices
- Scalable
- Opensource
- SQL's should define the "model"
- Because of its microservices and API driven nature "view" are delegeted to SPA or native applications (they also exist in frontend and frontend-native folders)
- It must be easily cloned and when executed it should run (*)
(*) This project uses MySQL. Because of the [license model of MySQL] (https://www.mysql.com/about/legal/licensing/oem/), if you use this boilerplate, do not distribute MySQL binaries.
- Ubuntu is prefered
- MySQL is chosen for user database
- Source code in
./frontend
directory - Web App is generated by create-react-app to have all wiring ready with babel and webpack
- SPA - Single Page Application approach is used
- Redux is used to track login state
- The common library Material UI which implements Google's material design principles, is used for Material Design UI components
- Source code in
./frontend-native
directory - Native App is generated by Expo to have all wiring ready and a test suite that does not require XCode, hence Mac ownership
- Redux is used to track login state
- The common library NativeBase is used for both iOS and Android UI components
- Source code in
./backend/src
directory - Based on Express
- All authentication is with JWT (the node library jsonwebtoken is used)
- Passwords are hashed by bcrypt
- Uses [MySQL] (https://www.mysql.com/) as the user repository database (*)
- For email uses nodemailer
(*) It is completely OK if you swap the MySQL with other databases. The database scripts are in pure SQL so it should, in theory, be fine to use with other relateional database servers.
-
If you are not using MySQL, you'll need to modify database connections in the code. That is why we suggest you to setup MySQL. For a clean guide to set up MySQL for Ubuntu yo can refer here.
-
Set environment parameters for mail and relational database. If you choose to use MySQL and linux adding following lines to
~/.bashrc
file should be sufficient. (Please update username, password, etc correctly.)
############# react-spa-jwt-authentication-boilerplate #############
# JWT Secret
export JWT_SECRET="your-secret-do-not-forget-to-change"
# Mail Transporter Parameters
export GENERIC_MAIL_SERVICE="yourmailtransporter" #Example: "gmail"
export GENERIC_MAIL_USER="yourusername" #Example: "[email protected]"
export GENERIC_MAIL_PASSWORD="yourpassword" #Example: "Password1:-)"
# MySQL Parameters
export MYSQL_HOST="yourhost" #Example "localhost"
export MYSQL_USER="yourdbuser" #Example "root"
export MYSQL_PASSWORD="yourdbpassword" #Example "tiger"
############# react-spa-jwt-authentication-boilerplate #############
If you are planning to use your gmail account as your mailer, you need to make the "Less secure app access" on from your gmail settings:
- Download codes
git clone https://github.com/MehmetKaplan/react-spa-jwt-authentication-boilerplate my-authentication-app
- Go to database script folder
cd my-authentication-app/backend/database_scripts
Skip below 2 steps, if you have another relational database system. But assure to generate a schema named AuthUsersDB and under that schema generate the objects stated in Generate_Objects.sql file.
- Generate the schema. (You'll need to provide root password).
mysql -u root -p < Generate_Database.sql
- Generate the objects. (You'll need to provide root password).
mysql -u root -p < Generate_Objects.sql
- Install modules for backend. (There may be warnings but assure there are no errors.)
cd [YOUR-ROOT-DIRECTORY]/backend
yarn install
mkdir dist
- Install modules for native appliation. (There may be warnings but assure there are no errors.)
cd [YOUR-ROOT-DIRECTORY]/frontend-native
yarn install
- Install modules for web appliation. (There may be warnings but assure there are no errors.)
cd [YOUR-ROOT-DIRECTORY]/frontend
yarn install
- Update the following configuration parameter both in
./frontend/src/common-logic/config.js
and./frontend-native/common-logic/config.js
. Please be aware that for expo application, since it runs in your phone, the most appropriate way would be to connect your computer to internet thorugh your phone via cable so that you have a stable connection. And use the IP of your computer instead oflocalhost
in below configuration.
mainServerBaseURL: "http" + "://" + "localhost" + ":" + "8000",
In seperate 2 terminals run following.
From root of project:
cd ./backend
yarn start
From root of project:
cd ./frontend
yarn start
In seperate 2 terminals run following sequentially (since start up sucks too much CPU power).
From root of project:
cd ./backend
yarn start
From root of project:
cd ./frontend-native
yarn start
Now you should see a QR code within the termical (cool! :-) ) which you may scan with your phone. And your phone will suggest you to open with "expo application". If that application is not loaded you should first install it.
When opening the native application through expo client, it takes a few minutes, be patient and reload a few times until you see javascript bundling info in the terminal. Something like:
Building JavaScript bundle [=== ] XX%
After you cloned the whole structure with following principles you can use the entire repo as your base and build your own single page web and react native applications on top of it.
frontend-native/common-logic
keeps the shared logic with web application. It must be same asfrontend/common-logic
. :-)- Components are not placed in any common area since components should deal only with presenting the data and it should be web / native specific.
- On the other hand logic of how the data is retrieved, manipulated and posted should be exactly the same for both web and native applications.
- Start with command
yarn start
which runs Expo application. Rest is same as you are working in an Expo application. - The layout of pages are components and you can find them under the
frontend-native/components
folder. Modifying them you can change the view of your project however you like. - The redux store is in the
frontend-native/common-logic/redux-store.js
file. You can update this file and use it similarly in your project.
frontend/common-logic
keeps the shared logic with web application. It must be same asfrontend-native/common-logic
. :-)- Start with command
yarn start
which runs a ReactJS application which is generated by create-react-app tool. - The layout of pages are components and you can find them under the
frontend/components
folder. Modifying them you can change the view of your project however you like. - The redux store is in the
frontend/common-logic/redux-store.js
file. You can update this file and use it similarly in your project.
- Start with command
yarn start
which runs Express application framework. Rest is same as you are working in an Express web application.- Middleware (the JS code that connects requests with responses) are not placed in a directory structure since the logic is pretty straight forward.
- All behaviour configurations should be placed under
backend/src/config.js
file. - Database selects are in
backend/src/sqls.js
so that from a single point the persistent layer interaction can be analysed. - The email communication with users is governed by
backend/src/mailer.js
. - The fraudelent requests are to be detected by
backend/src/lock_handler.js
. backend/database_scripts/database_action_mysql.js
governs communication with MySQL database with 2 simple wrapper functions. By default they are left as logging the sql statements that they are executing.backend/src/generic_library.js
keeps a few helper javascript function.backend/src/server.js
, as a standard Express application, keeps track of routes, all of which are API requests, except the web application (thefrontend
application)backend/src/validations.js
is resposible of the request parameters' validations.
Here we'll try to look at the infrastructure from different angles
- Roles
- Scenarios
- The flows in frontend
- The process flows
- React Component (Class) Flows
- User
- Browser or Native Application (their interaction with backend should be exactly the same)
- Request Handler
- Database
- Mailer
- Lock Handler
- Validations
The native and web frontend components are very similar. The reasons that they are not unified are:
- There are no consistent UI libraries that work similar for native and web. We use native-base in native and material ui in web frontend. They are the most used frameworks for their areas.
- Native application is generated by Expo and web application is generated by create-react-app. The two tools have slight differences in their navigation approaches.
We tried to unify these navigations as much as possible.
Below is the comparison of component flows in native and web application. As you see the difference is minimal.
For Facebook login, as a standard approach, you need to obtain the Application ID and and configure it in the ./frontend-native/common-logic/config.js
.
This id should propagate to ./frontend/src/common-logic/config.js
when the copy_common-logic.sh
is run under ./frontend-native/common-logic/
.
- Configure
"facebookScheme": "fbYOUR-FB-APP-ID",
parameter in the./frontend-native/app.json
file. Be careful that, there isfb
in front of your application id. - Configure
facebookAppId
andfacebookDisplayName
keys ny obtaining the values from https://docs.expo.io/versions/latest/sdk/facebook/ in section 4.
Also you'll need to follow instructions in https://docs.expo.io/versions/latest/sdk/facebook/.
- Go through environment variables and carry them
- Go through the config parameters
- Build the backend server and deploy the application
- Start up the application in production server
Follow the instructions in https://docs.expo.io/versions/latest/distribution/building-standalone-apps/#building-standalone-apps
- Have a public privcy policy URL and configure it in Facebook developers then change your Facebook application settings to production.
- For iOS, get your apps Bundle ID from iOS Developer Console and configure it in the Facebook developer page (during devlopment we have been using Expo's bundle id)
- For Android build your application, then go as stated in https://docs.expo.io/versions/latest/sdk/facebook/
- WebView must be tested on Android since it has differentiated code.
16.03.2019: For frontend-native background task runner added. This is a WebView class which executes delegated tasks (fetch as primary goal) at the background and gives back the result. The aim is to avoid the impact on user experience because of single-thread nature of the JavaScript. As of now Expo SDK32 has a bug that prevents reading data from the WebView. It is expected to be solved in SDK33.
31.03.2019: Implemented web worker structure for same purpose in frontend web side. 07.04.2019: Social Login Completed
The license is MIT and full text here.
- express license here
- jsonwebtoken license here
- bcrypt license here
- mysql license here
- nodemailer license here
- babel license here
- cors license here
- date-and-time license here
- rimraf license here
- morgan license here
- node-fetch license here