Skip to content

Commit 9ff6083

Browse files
committed
firebase authentication
1 parent 15e23d0 commit 9ff6083

File tree

11 files changed

+482
-0
lines changed

11 files changed

+482
-0
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.env
2+
*.pyc
3+
/__pycache__
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<!--Please do not remove this part-->
2+
![Star Badge](https://img.shields.io/static/v1?label=%F0%9F%8C%9F&message=If%20Useful&style=style=flat&color=BC4E99)
3+
![Open Source Love](https://badges.frapsoft.com/os/v1/open-source.svg?v=103)
4+
5+
# Firebase Authentication for Flask Application
6+
7+
## 🛠️ Description
8+
This project enables developers to implement secure user authentication features in their Flask applications with ease using Firebase Authentication which offers various authentication methods, including email/password, social media login (such as Google, Facebook, Twitter), and more. It handles the entire authentication process, including user registration, login, and password reset, taking care of security best practices like password hashing and token-based authentication.
9+
10+
## ⚙️ Languages or Frameworks Used
11+
- Flask, Firebase
12+
- HTML, CSS, Bootstrap
13+
14+
15+
## 🌟 How to run
16+
- ### Install all the requirements
17+
Run `pip install -r requirements.txt` to install all the requirements.
18+
- ### Firebase Setup for Project
19+
20+
- Create a [firebase](https://firebase.google.com/) project, set up a web project and get all the `Project Configurations` from `Project Settings`.
21+
22+
- Navigate to the **Authentication** section in your firebase project and enable the `Email and Password`
23+
authentication.
24+
25+
- The `Project Configurations` will look as follows :-
26+
```bash
27+
"apiKey": YOUR_API_KEY ,
28+
"authDomain": YOUR_AUTH_DOMAIN,
29+
"databaseURL": YOUR_DATABASEURL,
30+
"projectId": YOUR_PROJECT_ID,
31+
"storageBucket": YOUR_STORAGE_BUCKET,
32+
"messagingSenderId": YOUR_MESSAGING_SENDER_ID,
33+
"appId": YOUR_APP_ID,
34+
"measurementId": YOUR_MEASUREMENT_ID
35+
```
36+
- ### Setup Environment for the project
37+
- Now create a `.env` file in your project dreictory and include the following parameters as it is :-
38+
```bash
39+
export FIREBASE_APIKEY=YOUR_API_KEY
40+
export FIREBASE_AUTHDOMAIN=YOUR_AUTH_DOMAIN
41+
export FIREBASE_DATABASEURL=YOUR_DATABASEURL
42+
export FIREBASE_PROJECT_ID=YOUR_PROJECT_ID
43+
export FIREBASE_STORAGE_BUCKET=YOUR_STORAGE_BUCKET
44+
export FIREBASE_MESSAGING_SENDER_ID=YOUR_MESSAGING_SENDER_ID
45+
export FIREBASE_APP_ID=YOUR_APP_ID
46+
export FIREBASE_MEASUREMENT_ID=YOUR_MEASUREMENT_ID
47+
```
48+
49+
- ### Now Just, Run the project
50+
- To the run the project, go to the `bash` terminal of VSCode or any other code editor and run `./start_server.sh`.
51+
- You don't have to care about setting `.env` then yourself then.
52+
53+
54+
## 📺 Demo
55+
![image](https://github.com/MBSA-INFINITY/MBSA-Forms/assets/85332648/2200ef81-57de-4619-ba33-4bed2cf31780)
56+
![image](https://github.com/MBSA-INFINITY/MBSA-Forms/assets/85332648/ad83c91d-e140-4f4b-9b30-81b4903f1011)
57+
58+
## 🤖 Author
59+
60+
Github - [MBSA-INFINITY](https://github.com/MBSA-INFINITY)
61+
LinkedIn - [MBSAIADITYA](https://www.linkedin.com/in/mbsaiaditya/)
62+
Portfolio - [MBSA](https://mbsaiaditya.in/)
63+
64+
65+
66+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#Importing Firebase
2+
from firebase import Firebase
3+
import os
4+
5+
#Intializing Firebase Configuration from the Environment Variables
6+
config = {
7+
"apiKey": os.environ.get("FIREBASE_APIKEY"),
8+
"authDomain": os.environ.get("FIREBASE_AUTHDOMAIN"),
9+
"databaseURL": os.environ.get("FIREBASE_DATABASEURL"),
10+
"projectId": os.environ.get("FIREBASE_PROJECT_ID"),
11+
"storageBucket": os.environ.get("FIREBASE_STORAGE_BUCKET"),
12+
"messagingSenderId": os.environ.get("FIREBASE_MESSAGING_SENDER_ID"),
13+
"appId": os.environ.get("FIREBASE_APP_ID"),
14+
"measurementId": os.environ.get("FIREBASE_MEASUREMENT_ID")
15+
}
16+
17+
#Intializing Firebase Object
18+
firebase = Firebase(config)
19+
20+
#Intializing Firebase Databse
21+
db = firebase.database()
22+
23+
#Intializing Firebase Auth
24+
auth = firebase.auth()
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#Importing Flask and other important functions
2+
from flask import Flask, render_template, request, redirect, abort, flash, session ,url_for
3+
#Importing firebase auth from db.py
4+
from db import auth
5+
6+
app = Flask(__name__)
7+
app.secret_key = "MBSAIADITYA"
8+
9+
exempted_endpoints = ['signup','login','static']
10+
11+
'''
12+
Signup Route
13+
'''
14+
@app.route("/signup", methods = ['GET','POST'])
15+
def signup():
16+
if request.method=='POST':
17+
name = request.form.get("name")
18+
username = request.form.get("email")
19+
password = request.form.get("password")
20+
repassword = request.form.get("repassword")
21+
if password == repassword:
22+
if len(password)>=6:
23+
try:
24+
#Creating User in firebase using create_user_with_email_and_password method of firebase/auth
25+
_user_ = auth.create_user_with_email_and_password(username ,password)
26+
flash("User has been created successfully! Please Login")
27+
return redirect("/")
28+
except Exception as e:
29+
abort(500, {'message': str(e)})
30+
else:
31+
flash('Password is less than 6 characters!')
32+
return redirect("/signup")
33+
else:
34+
flash('Both Passwords do not match!')
35+
return redirect("/signup")
36+
return render_template("signup.html")
37+
38+
'''
39+
Login Route
40+
'''
41+
@app.route("/login",methods = ['GET','POST'] )
42+
def login():
43+
if request.method == 'POST':
44+
data = dict(request.form)
45+
email = data.get("email")
46+
password = data.get("password")
47+
try:
48+
#Signing User in firebase using sign_in_with_email_and_password method of firebase/auth
49+
user = auth.sign_in_with_email_and_password(email ,password)
50+
print(user)
51+
session['user'] = user['localId']
52+
session['email'] = user['email']
53+
return redirect("/")
54+
except Exception as e:
55+
abort(500, {'message': str(e)})
56+
57+
if 'user' in session:
58+
return redirect("/")
59+
return render_template("login.html")
60+
61+
'''
62+
Main dashboard route which has to be protected
63+
'''
64+
@app.route("/",methods = ['GET','POST'])
65+
def start():
66+
return render_template("index.html", user=session['email'])
67+
68+
'''
69+
Logout Route
70+
'''
71+
@app.route("/logout",methods = ['GET','POST'])
72+
def logout():
73+
session.pop('user')
74+
session.pop('email')
75+
flash("User logged out successfully!")
76+
return redirect("/")
77+
78+
79+
'''This is an important middleware that run before any request made to flask application and checks
80+
when user is authenticated or not!
81+
'''
82+
83+
@app.before_request
84+
def before_request_func():
85+
if request.endpoint in exempted_endpoints:
86+
return
87+
if 'user' not in session:
88+
return redirect(url_for('login'))
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Flask==2.0.1
2+
firebase==3.0.1
3+
python-jwt==4.0.0
4+
gcloud==0.18.3
5+
sseclient==0.0.27
6+
pycryptodome==3.18.0
7+
requests-toolbelt==0.10.1
8+
urllib3==1.26.15
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from main import app
2+
if __name__ == '__main__':
3+
app.run()
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
source .env
2+
python run.py
Loading
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Document</title>
7+
</head>
8+
<body>
9+
Hi {{user}} <br>
10+
<a href="/logout">Logout</a>
11+
12+
</body>
13+
</html>
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1">
6+
<title>Login</title>
7+
<link rel="shortcut icon" href="{{url_for('static',filename='login.png')}}" type="image/x-icon">
8+
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
9+
</head>
10+
<style>
11+
.bd-placeholder-img {
12+
font-size: 1.125rem;
13+
text-anchor: middle;
14+
-webkit-user-select: none;
15+
-moz-user-select: none;
16+
user-select: none;
17+
}
18+
19+
@media (min-width: 768px) {
20+
.bd-placeholder-img-lg {
21+
font-size: 3.5rem;
22+
}
23+
}
24+
25+
.b-example-divider {
26+
height: 3rem;
27+
background-color: rgba(0, 0, 0, .1);
28+
border: solid rgba(0, 0, 0, .15);
29+
border-width: 1px 0;
30+
box-shadow: inset 0 .5em 1.5em rgba(0, 0, 0, .1), inset 0 .125em .5em rgba(0, 0, 0, .15);
31+
}
32+
33+
.b-example-vr {
34+
flex-shrink: 0;
35+
width: 1.5rem;
36+
height: 100vh;
37+
}
38+
39+
.bi {
40+
vertical-align: -.125em;
41+
fill: currentColor;
42+
}
43+
44+
.nav-scroller {
45+
position: relative;
46+
z-index: 2;
47+
height: 2.75rem;
48+
overflow-y: hidden;
49+
}
50+
51+
.nav-scroller .nav {
52+
display: flex;
53+
flex-wrap: nowrap;
54+
padding-bottom: 1rem;
55+
margin-top: -1px;
56+
overflow-x: auto;
57+
text-align: center;
58+
white-space: nowrap;
59+
-webkit-overflow-scrolling: touch;
60+
}
61+
html,
62+
body {
63+
height: 100%;
64+
}
65+
66+
body {
67+
display: flex;
68+
align-items: center;
69+
padding-top: 40px;
70+
padding-bottom: 40px;
71+
background-color: #f5f5f5;
72+
}
73+
74+
.form-signin {
75+
max-width: 330px;
76+
padding: 15px;
77+
}
78+
79+
.form-signin .form-floating:focus-within {
80+
z-index: 2;
81+
}
82+
83+
.form-signin input[type="email"] {
84+
margin-bottom: -1px;
85+
border-bottom-right-radius: 0;
86+
border-bottom-left-radius: 0;
87+
}
88+
89+
.form-signin input[type="password"] {
90+
margin-bottom: 10px;
91+
border-top-left-radius: 0;
92+
border-top-right-radius: 0;
93+
}
94+
</style>
95+
96+
<body class="text-center">
97+
<main class="form-signin w-100 m-auto">
98+
{% with messages = get_flashed_messages() %}
99+
{% if messages %}
100+
<ul class=flashes>
101+
{% for message in messages %}
102+
<div class="alert alert-warning alert-dismissible fade show" role="alert">
103+
<strong>{{message}}</strong>
104+
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
105+
</div>
106+
{% endfor %}
107+
</ul>
108+
{% endif %}
109+
{% endwith %}
110+
<form method="post" action="/login" autocomplete="off">
111+
<img class="mb-4" src="{{url_for('static',filename='login.png')}}" alt="" width="100" height="100">
112+
<h1 class="h3 mb-3 fw-normal">Login Page</h1>
113+
114+
<div class="form-floating">
115+
<input type="email" class="form-control" id="floatingInput" name="email" placeholder="[email protected]" required>
116+
<label for="floatingInput">Email address</label>
117+
</div>
118+
<div class="form-floating">
119+
<input type="password" class="form-control" id="floatingPassword" name="password" placeholder="Password" required>
120+
<label for="floatingPassword">Password</label>
121+
</div>
122+
123+
<a href="/signup"><span><b>New User?</b></span></a> <br>
124+
<button class="w-100 btn btn-lg btn-primary" type="submit">Log in</button>
125+
<p class="mt-5 mb-3 text-muted"><a href="https://github.com/MBSA-INFINITY">MBSA</a> &copy; 2023 - 2024</p>
126+
</form>
127+
</main>
128+
129+
130+
131+
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
132+
</body>
133+
</html>

0 commit comments

Comments
 (0)