Skip to content

WebNinjaDeveloper.com

Programming Tutorials




Menu
  • Home
  • Youtube Channel
  • Official Blog
  • Nearby Places Finder
  • Direction Route Finder
  • Distance & Time Calculator
Menu

Python 3 Flask-Login Project to Build Google OAuth2 Login & Logout System Using SQLite Database in Browser

Posted on December 19, 2022

Welcome folks today in this blog post we will be building the google oauth2 user login and logout oauth2 system in browser using flask-login and sqlite database. All the full source code of the application is shown below.

 

 

Get Started

 

 

In order to get started you need to create the requirements.txt file inside the root directory and copy paste the following code

 

 

requirements.txt

 

 

1
2
3
4
5
requests==2.21.0
Flask==1.0.2
oauthlib==3.0.1
pyOpenSSL==19.0.0
Flask-Login==0.4.1

 

 

As you can see in the above file we have declared all the dependencies which is needed for this flask project. Now using the pip command install these as shown below

 

 

pip install -r requirements.txt

 

 

Directory Structure

 

 

 

 

Now we need to create the schema.sql file which will be the actual user data that we will be storing for this oauth2 google login and logout system

 

 

schema.sql

 

 

1
2
3
4
5
6
CREATE TABLE user (
  id TEXT PRIMARY KEY,
  name TEXT NOT NULL,
  email TEXT UNIQUE NOT NULL,
  profile_pic TEXT NOT NULL
);

 

 

As you can see we are creating the user table in which we have four fields namely the id of the user which is the primary key, And then we have the name of the user, and then we have the email, and the profile picture as well.

 

 

Creating Database

 

 

Now we will be creating the database file which will be db.py here we will be creating the sqlite db as shown below

 

 

db.py

 

 

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# http://flask.pocoo.org/docs/1.0/tutorial/database/
import sqlite3
 
import click
from flask import current_app, g
from flask.cli import with_appcontext
 
 
def get_db():
    if "db" not in g:
        g.db = sqlite3.connect(
            "sqlite_db", detect_types=sqlite3.PARSE_DECLTYPES
        )
        g.db.row_factory = sqlite3.Row
 
    return g.db
 
 
def close_db(e=None):
    db = g.pop("db", None)
 
    if db is not None:
        db.close()
 
 
def init_db():
    db = get_db()
 
    with current_app.open_resource("schema.sql") as f:
        db.executescript(f.read().decode("utf8"))
 
 
@click.command("init-db")
@with_appcontext
def init_db_command():
    """Clear the existing data and create new tables."""
    init_db()
    click.echo("Initialized the database.")
 
 
def init_app(app):
    app.teardown_appcontext(close_db)
    app.cli.add_command(init_db_command)

 

 

As you can see it contains a variety of methods to get the db, and to create the database. So now guys we need to create the user model file called user.py

 

 

user.py

 

 

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
from flask_login import UserMixin
 
from db import get_db
 
 
class User(UserMixin):
    def __init__(self, id_, name, email, profile_pic):
        self.id = id_
        self.name = name
        self.email = email
        self.profile_pic = profile_pic
 
    @staticmethod
    def get(user_id):
        db = get_db()
        user = db.execute(
            "SELECT * FROM user WHERE id = ?", (user_id,)
        ).fetchone()
        if not user:
            return None
 
        user = User(
            id_=user[0], name=user[1], email=user[2], profile_pic=user[3]
        )
        return user
 
    @staticmethod
    def create(id_, name, email, profile_pic):
        db = get_db()
        db.execute(
            "INSERT INTO user (id, name, email, profile_pic)"
            " VALUES (?, ?, ?, ?)",
            (id_, name, email, profile_pic),
        )
        db.commit()

 

 

As you can see it contains the methods for inserting the user information directly into the user tables by using the INSERT Statement. And also if you want to select the information about any user. You can use the SELECT Statement.

 

 

Creating .env File

 

 

Now guys we want the client_id and client_secret from the google cloud console. Just copy paste the values inside the below code. Here we are creating the .env file to store these values

 

 

.env

 

 

1
2
GOOGLE_CLIENT_ID=####yourclientid####
GOOGLE_CLIENT_SECRET=####yourclientsecret####

 

 

Now guys we want to create the app.py file and copy paste the following code

 

 

app.py

 

 

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# Python standard libraries
import json
import os
import sqlite3
 
os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
 
# Third party libraries
from flask import Flask, redirect, request, url_for
from flask_login import (
    LoginManager,
    current_user,
    login_required,
    login_user,
    logout_user,
)
from oauthlib.oauth2 import WebApplicationClient
import requests
 
# Internal imports
from db import init_db_command
from user import User
 
# Configuration
GOOGLE_CLIENT_ID = os.environ.get("GOOGLE_CLIENT_ID", None)
GOOGLE_CLIENT_SECRET = os.environ.get("GOOGLE_CLIENT_SECRET", None)
GOOGLE_DISCOVERY_URL = (
    "https://accounts.google.com/.well-known/openid-configuration"
)
 
# Flask app setup
app = Flask(__name__)
app.secret_key = os.environ.get("SECRET_KEY") or os.urandom(24)
 
 
 
if __name__ == "__main__":
    app.run(debug=True)

 

 

As you can see we are importing all the required dependencies at the very top. And then we are initializing an OAuth2 config variables including the client_id and the client_secret from the environment variables. And then we are starting out the flask app at port 5000.

 

 

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# User session management setup
# https://flask-login.readthedocs.io/en/latest
login_manager = LoginManager()
login_manager.init_app(app)
 
 
@login_manager.unauthorized_handler
def unauthorized():
    return "You must be logged in to access this content.", 403
 
 
# Naive database setup
try:
    init_db_command()
except sqlite3.OperationalError:
    # Assume it's already been created
    pass
 
# OAuth2 client setup
client = WebApplicationClient(GOOGLE_CLIENT_ID)
 
 
# Flask-Login helper to retrieve a user from our db
@login_manager.user_loader
def load_user(user_id):
    return User.get(user_id)

 

 

As you can see we are starting out the flask login manager passing the app object. And then we are initializing a new google oauth2 web client. And then inside the try block we are creating the sqlite database whenever your application runs for the very first time. Now execute the app.py it will look something like this

 

 

python app.py

 

 

 

 

Now we need to create the index route which will be the homepage of the application

 

 

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
@app.route("/")
def index():
    if current_user.is_authenticated:
        return (
            "<p>Hello, {}! You're logged in! Email: {}</p>"
            "<div><p>Google Profile Picture:</p>"
            '<img src="{}" alt="Google profile pic"></img></div>'
            '<a class="button" href="/logout">Logout</a>'.format(
                current_user.name, current_user.email, current_user.profile_pic
            )
        )
    else:
        return '<a class="button" href="/login">Google Login</a>'

 

 

As you can see we are displaying a simple welcome message to the user if he or she is authenticated. The different details are shown such as the email and profile pic. And also we have the logout button. And if the user is not authenticated then we are showing the user with a anchor tag which says Google Login as shown below

 

 

 

Getting Authorization Code Using OAuth2 Flow

 

 

 

Now we will redirect the user to the oauth2 redirect url inside the browser when the user goes to the /login route as shown below

 

 

 

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@app.route("/login")
def login():
    # Find out what URL to hit for Google login
    google_provider_cfg = get_google_provider_cfg()
    authorization_endpoint = google_provider_cfg["authorization_endpoint"]
 
    # Use library to construct the request for login and provide
    # scopes that let you retrieve user's profile from Google
    request_uri = client.prepare_request_uri(
        authorization_endpoint,
        redirect_uri=request.base_url + "/callback",
        scope=["openid", "email", "profile"],
    )
    print(request.base_url + "/callback")
    return redirect(request_uri)

 

 

As you can see we are passing the authorization endpoint and redirect_uri of the project. And also we are providing the scopes that we need to user access. Here we are providing the userprofile and email

 

 

 

 

 

Getting Access Token From Authorization Code

 

 

Now guys we will be getting the access token from the authorization code to display the profile details of the user. For this we need to copy paste the following code

 

 

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
@app.route("/login/callback")
def callback():
    # Get authorization code Google sent back to you
    code = request.args.get("code")
 
    # Find out what URL to hit to get tokens that allow you to ask for
    # things on behalf of a user
    google_provider_cfg = get_google_provider_cfg()
    token_endpoint = google_provider_cfg["token_endpoint"]
 
    # Prepare and send request to get tokens! Yay tokens!
    token_url, headers, body = client.prepare_token_request(
        token_endpoint,
        authorization_response=request.url,
        redirect_url=request.base_url,
        code=code,
    )
    token_response = requests.post(
        token_url,
        headers=headers,
        data=body,
        auth=(GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET),
    )
 
    # Parse the tokens!
    client.parse_request_body_response(json.dumps(token_response.json()))
 
    # Now that we have tokens (yay) let's find and hit URL
    # from Google that gives you user's profile information,
    # including their Google Profile Image and Email
    userinfo_endpoint = google_provider_cfg["userinfo_endpoint"]
    uri, headers, body = client.add_token(userinfo_endpoint)
    userinfo_response = requests.get(uri, headers=headers, data=body)
    print(userinfo_response.json())
 
    # We want to make sure their email is verified.
    # The user authenticated with Google, authorized our
    # app, and now we've verified their email through Google!
    if userinfo_response.json().get("email_verified"):
        unique_id = userinfo_response.json()["sub"]
        users_email = userinfo_response.json()["email"]
        picture = userinfo_response.json()["picture"]
        users_name = userinfo_response.json()["given_name"]
    else:
        return "User email not available or not verified by Google.", 400
 
    # Create a user in our db with the information provided
    # by Google
    user = User(
        id_=unique_id, name=users_name, email=users_email, profile_pic=picture
    )
 
    # Doesn't exist? Add to database
    if not User.get(unique_id):
        User.create(unique_id, users_name, users_email, picture)
 
    # Begin user session by logging the user in
    login_user(user)
 
    # Send user back to homepage
    return redirect(url_for("index"))
 
 
def get_google_provider_cfg():
    return requests.get(GOOGLE_DISCOVERY_URL).json()

 

 

As you can see we are getting the user profile information and we are storing it inside the sqlite database. And lastly we are redirecting the user to the index page

 

 

 

 

 

Logout the User

 

 

Now guys we need to write the code to successfully logout the user as shown below.

 

 

Python
1
2
3
4
5
@app.route("/logout")
@login_required
def logout():
    logout_user()
    return redirect(url_for("index"))

 

 

BUY FULL SOURCE CODE Using VISA CARD

 

BUY FULL SOURCE CODE Using UPI & Bank

Recent Posts

  • Angular 14/15 JWT Login & Registration Auth System in Node.js & Express Using MongoDB in Browser
  • Build a JWT Login & Registration Auth System in Node.js & Express Using MongoDB in Browser
  • React-Admin Example to Create CRUD REST API Using JSON-Server Library in Browser Using Javascript
  • Javascript Papaparse Example to Parse CSV Files and Export to JSON File and Download it as Attachment
  • Javascript Select2.js Example to Display Single & Multi-Select Dropdown & Fetch Remote Data Using Ajax in Dropdown
  • Angular
  • Bunjs
  • C#
  • Deno
  • django
  • Electronjs
  • java
  • javascript
  • Koajs
  • kotlin
  • Laravel
  • meteorjs
  • Nestjs
  • Nextjs
  • Nodejs
  • PHP
  • Python
  • React
  • ReactNative
  • Svelte
  • Tutorials
  • Vuejs




©2023 WebNinjaDeveloper.com | Design: Newspaperly WordPress Theme