A complete login application
- DockerHub image: login-boilerplate
- Python >= v3.8
- Postgresql == 12
- Docker >= 20.10.6
- Docker-compose >= 1.26.0
- PGAdmin (docker) latest (as per 2022-02-06)
- Redis Master-Slave (docker) >= 6.2.0
As today (2022-02-06), the database stacks are deployed in vultr and are remotely accessed by the LoginApp which is deployed on the Heroku. PS: I personally named it as YALA: Yet Another Login Aplication Boilerplate. You can access the deployed app here: LoginApp Page
There will be three github projects for this Login App:
- Api Service (This repository)
- Email Publisher
- For the initial phase, it uses a internal class to demonstrate the complete logic (In this repo @
app/utils/email_publisher.py
)
- For the initial phase, it uses a internal class to demonstrate the complete logic (In this repo @
- Admin Dashboard
- For the initial phase, it adopts Bootstrap-Simple-Admin-Template
to demonstrate the complete logic (In this repo @
app/webapps
)- FYI: it is also a good practice to implement how we differenciate between exposed endpoints used for APIs and disclosed endpoints used for web apps (with Jinja
- In the future, I plan to build an independent project with React-Admin from Marmelab
- For the initial phase, it adopts Bootstrap-Simple-Admin-Template
to demonstrate the complete logic (In this repo @
-
Simple schema for table
user
:No Table Name Data Type 1 id (PK) int 2 name varchar 3 email varchar 4 hashed_password varchar 5 total_login int 6 signup_by varchar 7 activated bool 8 session_at datetime 9 created_at datetime 10 updated_at datetime
- Prepare the core backend framework; In this case I used FastAPI boilerplate
from the official.
- FYI: For simplier usage, I ended up using This template which simplified the official's with more updated packages.
- User registration by email
- Registration form
- Verification link generator
- Verify email when register by using email & password by sending the link in the email
- Multiple login scenarios:
- Login by email & password (will have a register page)
- Login by Facebook account
- Login by Google account
- Adding more social login and any global login integration
- Backend functionalities
- Clean code architecture
- Decoupled system settings
- Dummy data generator for testing usage
- CRUD for user data
- Database connection with asyncpg
- Cache with aioredis for access token and refresh token blacklist management
- API routes (exposed schema) and Webapp routes (disclosed schema)
- FYI: Some APIs were not finalized yet, as it is not currently used for now
- API documentation (FastAPI default feature)
- Dashboard
- Internal integration with bootstrap admin using Jinja2 templates
- Select and integrate an open sourced simple admin dashboard
- Implement the webapp functionalities
- Login by Email & Password
- Login by Facebook account
- Login by Google account
- Get and edit user profile
- List of users
- Simple statistics for dashboard
- Integration with any other admin dashboard
- Prepare the admin dashboard project
- To Adopt Marmelab Reactjs Admin template
- Internal integration with bootstrap admin using Jinja2 templates
- Test automation
- Add robot framework files to test the APIs
- Unit Tests
- Authentication
- TBD
- Local Deployment (Tested with Ubuntu 20.04)
- Prepare the environment for local deployment:
- Install
venv
:sudo apt-get install python3-venv
- Create python environment:
python3 -m venv venv
- Activate:
- Bash Shell:
. venv/bin/activate
- Fish Shell:
. venv/bin/activate.fish
- Bash Shell:
- Upgrade pip:
pip install --upgrade pip
- Install
poetry
:pip install poetry
- Install all requirements with poetry:
poetry install
- Alembic initialization (OPTIONAL):
alembic revision --autogenerate -m "initialization"
- This script will create a python file in
alembic/versions/*.py
- FYI: By default. I have prepared the file
2022_01_28_1243_initialization__868253e3f0c7.py
inside thealembic/versions
.
- This script will create a python file in
- Once this file generates we are ready for database migration,
Run following command:
alembic upgrade head
- Run initialized data
bash init.sh
- This will create a superuser data that can be used to login.
- Created user:
email = [email protected] pass = OdLknKQJMUwuhpAVHvRC1
- Now, you are ready to run the service. :)
- Install
- Run the database with compose:
docker-compose -f docker-compose-db-only.yml --env-file .env.compose up -d --remove-orphans
- Here I use a docker-compose for the database to simplify the deployment. :)
- To stop, run:
docker-compose -f docker-compose-db-only.yml --env-file .env.compose down
- Run api-service:
uvicorn app.main:app --reload
- Open on the browser: http://localhost:8000
- Prepare the environment for local deployment:
- Docker-compose
- Run compose:
docker-compose --env-file .env.compose up -d --remove-orphans
- FYI: You can add
--build
on the end of the script to enforce the build in every execution
- FYI: You can add
- Open on the browser: http://localhost:8001
- Run compose:
- Accessing database via PGAdmin
- Open PGAdmin in your favorite browser:
http://localhost:5050/
- Use any terminal and get the Internal IP of your deployed posgresql
- First, inspect the docker network detail:
$ docker network inspect loginapp_database
- Find
Containers
and locate the IP (=IPv4Address
) of yourlogin_postgresdb
service[ { "Name": "loginapp_database", ... "Containers": { ... "a8747105a949cadeeace7f296f112ca3deb60d9ff2e43c4676170c8957de16a9": { "Name": "login_postgresdb", "EndpointID": "296a5ba37862f6e8ccc3d5cfdaff957559e3191f0b311d5406e5e161bf950f02", "MacAddress": "02:42:c0:a8:50:02", "IPv4Address": "192.168.80.2/20", "IPv6Address": "" }, ... }, ... } ]
- In my case, the IP that I am looking for is
192.168.80.2
- Why not
localhost
? Of couse! Since they are communicating privately inside the docker network. ;)
- Find
- Now, back to the browser and
Add New Server
- In the
General
tab, you can define any name, e.g.,myserver
- Then, go to
Connection
tab, and put following information:Hostname/Address
put yourIPv4Address
you found before, which is192.168.80.2
for my casePort
put5432
; Remember that it uses the INTERNAL PORT, not the exposed network, dude. ;)Maintainance database
putdefault_db
Username
putrDGJeEDqAz
Password
putXsPQhCoEfOQZueDjsILetLDUvbvSxAMnrVtgVZpmdcSssUgbvs
- Finally, press the
Save
button!
- First, inspect the docker network detail:
- ALTERNATIVE: As some devs prefer using a terminal, use this commands:
- Connecting to db:
$ psql -h localhost -d default_db -U rDGJeEDqAz -p 5387
- FYI: You are accessing the database from outside the terminal, so you use an EXPOSED PORT,
which is
5387
.
- FYI: You are accessing the database from outside the terminal, so you use an EXPOSED PORT,
which is
- Then, it will ask for your password, and put
XsPQhCoEfOQZueDjsILetLDUvbvSxAMnrVtgVZpmdcSssUgbvs
- Connecting to db:
- Open PGAdmin in your favorite browser:
- Tiangolo for the awesome FastAPI framework!
- Rafsaf for the effort to in simplifying the official's boilerplate!
- Alexis Luna for the simple yet beautiful admin template!
- Fontawesome for your awesomeness!
- Database:
- Login with terminal:
psql -h <ip_or_domain> -d <db_name> -U <user> -p <port>
- Truncate
user
table (after logging in):TRUNCATE TABLE public.user;
- Login with terminal:
- Docker and Docker-compose
sudo apt install docker.io && sudo apt install docker-compose
- Redis:
- Terminal:
- Login to redis:
redis-cli -h <ip_or_domain> -p 6379
- Auth password:
<ip_or_domain>:6379> AUTH <password>
- Login to redis:
- Terminal:
- Heroku:
- Login:
heroku login
- Create a new repo:
heroku create
- You will get an output like these:
› Warning: heroku update available from 7.59.1 to 7.59.2. Creating app... done, ⬢ shielded-lowlands-46380 https://shielded-lowlands-46380.herokuapp.com/ | https://git.heroku.com/shielded-lowlands-46380.git
- In this case you have created a repo
https://git.heroku.com/shielded-lowlands-46380.git
- You will get an output like these:
- Clone repo locally:
$ git clone https://git.heroku.com/shielded-lowlands-46380.git
- Go to the project directory:
cd shielded-lowlands-46380
- Tailing the log:
heroku logs --tail
- Login:
- Sending email with Gmail and deploy it into Heroku
- Try and close all open gmail accounts except the one you plan to use as the mailer.
- Navigate to https://accounts.google.com/b/0/DisplayUnlockCaptcha, while that page is open redeploy the app via heroku. You should be good after that.