T-4004 / thesisGroup4.github.io

0 stars 0 forks source link

Task Tile #2

Open T-4004 opened 5 months ago

T-4004 commented 5 months ago

What - description of what you me to do Example: Hey @autopilot implement a Google sign-in on my website. Make changes to the front end and the back end of the application

Why - explain why this is important Example: I want to allow users to signup and login using their Google account

codeautopilot[bot] commented 5 months ago

Potential solution

To implement Google sign-in on a website, we need to update both the front-end and back-end components. The front-end will include a Google sign-in button and the necessary JavaScript to handle the sign-in process. The back-end will handle the OAuth flow, create/update user records, and manage user sessions.

How to implement

Backend (app.py and data.py)

app.py

from flask import Flask, redirect, url_for
from flask_login import LoginManager, login_user, logout_user, login_required
from authlib.integrations.flask_client import OAuth

app = Flask(__name__)
app.secret_key = 'your_secret_key'

login_manager = LoginManager()
login_manager.init_app(app)

oauth = OAuth(app)
google = oauth.register(
    name='google',
    client_id='your_client_id',
    client_secret='your_client_secret',
    access_token_url='https://accounts.google.com/o/oauth2/token',
    authorize_url='https://accounts.google.com/o/oauth2/auth',
    api_base_url='https://www.googleapis.com/oauth2/v1/',
    client_kwargs={'scope': 'openid profile email'},
)

@login_manager.user_loader
def load_user(user_id):
    # Load the user from the database
    return user

@app.route('/login')
def login():
    redirect_uri = url_for('authorize', _external=True)
    return google.authorize_redirect(redirect_uri)

@app.route('/authorize')
def authorize():
    token = google.authorize_access_token()
    resp = google.get('userinfo')
    user_info = resp.json()
    # Check if user exists in the database, if not create a new one
    user = User.get_or_create(user_info)
    login_user(user)
    return redirect('/')

@app.route('/logout')
@login_required
def logout():
    logout_user()
    return redirect('/')

if __name__ == '__main__':
    app.run(debug=True)

data.py

import mysql.connector

connection = mysql.connector.connect(
    host="your_host",
    user="your_username",
    password="your_password",
    database="your_database"
)

def insert_google_user(google_id, email):
    cursor = connection.cursor()
    query = "INSERT INTO users (google_id, email) VALUES (%s, %s)"
    values = (google_id, email)
    cursor.execute(query, values)
    connection.commit()
    cursor.close()

def get_user_by_google_id(google_id):
    cursor = connection.cursor(dictionary=True)
    query = "SELECT * FROM users WHERE google_id = %s"
    cursor.execute(query, (google_id,))
    user = cursor.fetchone()
    cursor.close()
    return user

connection.close()

Frontend (index.html, style.css, script.js)

templates/index.html

<!-- Include the Google API JavaScript library -->
<script src="https://apis.google.com/js/platform.js" async defer></script>
<script>
    function onSignIn(googleUser) {
        // Handle sign-in
    }
</script>
<!-- Add a div for the Google sign-in button -->
<div class="g-signin2" data-onsuccess="onSignIn"></div>

static/css/style.css

.google-signin-btn {
    /* Styles for Google sign-in button */
}

.google-signin-btn:hover {
    /* Hover state styles */
}

.google-signin-btn:active {
    /* Active state styles */
}

static/js/script.js

function initGoogleSignIn() {
    gapi.load('auth2', function() {
        gapi.auth2.init({
            client_id: 'YOUR_CLIENT_ID.apps.googleusercontent.com',
        });
    });
}

function onSignIn(googleUser) {
    // Handle the sign-in event
}

document.addEventListener('DOMContentLoaded', () => {
    initGoogleSignIn();
});

Ensure that you replace placeholders like 'your_client_id', 'your_client_secret', and 'your_secret_key' with actual values from your Google Developer Console and your application's configuration.

Click here to create a Pull Request with the proposed solution

Files used for this task:

Changes on data.py To accommodate new user data from Google sign-in, we need to modify the `data.py` file to include operations that will handle the insertion and retrieval of user data related to Google accounts. Here's a practical proposal for the changes: 1. **Create a table for users**: If not already present, create a table in the MySQL database to store user information. This table should include fields for storing Google-specific data such as the Google user ID and the email address associated with the Google account. 2. **Define functions to interact with the database**: Implement functions to insert new user data into the database and to retrieve existing user data based on the Google user ID. Here's an example of how you might modify the `data.py` file: ```python import mysql.connector # Establishing the connection connection = mysql.connector.connect( host="your_host", user="your_username", password="your_password", database="your_database" ) # Checking if the connection is successful if connection.is_connected(): print("Connected to MySQL database") # Function to insert a new user from Google sign-in def insert_google_user(google_id, email): cursor = connection.cursor() query = "INSERT INTO users (google_id, email) VALUES (%s, %s)" values = (google_id, email) cursor.execute(query, values) connection.commit() cursor.close() # Function to retrieve a user by Google ID def get_user_by_google_id(google_id): cursor = connection.cursor(dictionary=True) query = "SELECT * FROM users WHERE google_id = %s" cursor.execute(query, (google_id,)) user = cursor.fetchone() cursor.close() return user # Perform other database operations as needed # Closing the connection connection.close() ``` **Note**: The above code assumes that there is a table named `users` with columns `google_id` and `email`. You will need to adjust the table name and column names to match your actual database schema. **Important**: Don't forget to handle exceptions and edge cases, such as what happens if the user already exists in the database. Also, ensure that you are managing the database connection properly, opening it when needed and closing it after operations are complete to avoid resource leaks. Lastly, make sure to secure your database credentials and consider using environment variables or a configuration file to store sensitive information rather than hardcoding it into your script.
Changes on static/css/style.css To update the `style.css` file to style the Google sign-in button appropriately, you can follow these steps: 1. Define a class for the Google sign-in button that sets its appearance and dimensions. Google provides branding guidelines for their sign-in button, which should be followed to ensure consistency and familiarity for users. 2. Add any necessary hover and active state styles to provide visual feedback when the user interacts with the button. Here's an example of how you might add the styles for the Google sign-in button: ```css /* Add to the existing style.css content */ /* Google Sign-in Button Styles */ .google-signin-btn { background-color: #4285F4; /* Google blue */ color: white; padding: 10px 20px; border: none; border-radius: 2px; font-size: 16px; font-weight: bold; text-align: center; cursor: pointer; display: inline-block; margin: 20px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); } .google-signin-btn:hover { background-color: #357ae8; /* Slightly darker Google blue */ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3); } .google-signin-btn:active { background-color: #3367D6; /* Even darker Google blue */ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3); } /* Add a class for the icon inside the button if needed */ .google-signin-btn-icon { margin-right: 10px; vertical-align: middle; } /* Ensure the button text aligns with the icon */ .google-signin-btn-text { vertical-align: middle; } ``` This CSS will style the Google sign-in button with Google's brand blue color, make the text white, and add some padding and border radius to make it look like a button. It also includes styles for hover and active states to give visual feedback to the user. Remember to replace the placeholder class names with the actual class names used in your HTML if they are different. Also, ensure that the button's size and other properties match the design of your website for a consistent user experience.
Changes on templates/index.html To add a Google sign-in button to the HTML template, you will need to include the necessary HTML and JavaScript to integrate Google's sign-in API. Here's a practical proposal for modifying the `templates/index.html` file: 1. Add a div element to contain the Google sign-in button. 2. Include the Google API JavaScript library. 3. Add a script to configure the Google sign-in client. Here's how you can modify the `index.html` file: ```html Real-time Face Recognition

Real-time Face Recognition

Video Feed
``` In the above code: - The `` line includes the Google API JavaScript library which is necessary for the sign-in button to function. - The `onSignIn` function is a placeholder where you will handle the user's sign-in information. You will need to implement the logic to send this information to your server. - The `
` line adds the Google sign-in button to your page. The `data-onsuccess` attribute specifies the callback function to be called on successful sign-in. Remember to style the Google sign-in button appropriately in your `static/css/style.css` file to match the design of your website.
Changes on static/js/script.js To implement the Google sign-in process and handle the sign-in response, you will need to integrate the Google Sign-In JavaScript client library into the existing `script.js` file. Here's a practical proposal for how to do this: 1. Load the Google Sign-In JavaScript client library by adding the following script tag to your HTML file (not in `script.js` but it's important to mention for context): ```html ``` 2. Configure the Google Sign-In client with your application's client ID. This is typically done in the HTML file, but you can also do it in `script.js`: ```javascript function initGoogleSignIn() { gapi.load('auth2', function() { // Initialize the Google auth2 library gapi.auth2.init({ client_id: 'YOUR_CLIENT_ID.apps.googleusercontent.com', // Add additional options if necessary }); }); } ``` 3. Add a function to handle the sign-in event: ```javascript function onSignIn(googleUser) { // Get the user's profile information var profile = googleUser.getBasicProfile(); console.log('ID: ' + profile.getId()); console.log('Full Name: ' + profile.getName()); console.log('Given Name: ' + profile.getGivenName()); console.log('Family Name: ' + profile.getFamilyName()); console.log('Image URL: ' + profile.getImageUrl()); console.log('Email: ' + profile.getEmail()); // The ID token you need to pass to your backend: var id_token = googleUser.getAuthResponse().id_token; console.log('ID Token: ' + id_token); // Send the ID token to your server with an AJAX or fetch request // ... } ``` 4. Add a sign-in button to your HTML file (again, not in `script.js` but necessary for context): ```html
``` 5. Modify the DOMContentLoaded event listener to also initialize the Google Sign-In client: ```javascript document.addEventListener('DOMContentLoaded', () => { // Existing code to start webcam and capture image // ... // Initialize Google Sign-In initGoogleSignIn(); }); ``` 6. Add error handling for sign-in failure: ```javascript function signInFailure(error) { console.log('Sign-in error:', error); // Handle sign-in errors here, such as displaying a message to the user } ``` 7. Add a sign-out function if you want to provide users with the ability to sign out: ```javascript function signOut() { var auth2 = gapi.auth2.getAuthInstance(); auth2.signOut().then(function () { console.log('User signed out.'); // Perform any additional cleanup or UI updates after sign-out }); } ``` Remember to replace `'YOUR_CLIENT_ID.apps.googleusercontent.com'` with your actual client ID from the Google Developer Console. Also, ensure that you handle the ID token securely and verify it on the server side. This proposal outlines the necessary steps to integrate Google Sign-In into the existing JavaScript file. You will need to adjust the actual implementation based on the specific requirements and structure of your application.
Changes on app.py To update the Flask application to handle the Google OAuth flow, create/update user records, and manage user sessions, you will need to perform the following steps: 1. **Install Required Libraries**: You will need to install the `authlib` library, which provides an easy way to integrate OAuth in Flask applications. ```bash pip install authlib flask-login ``` 2. **Create OAuth Client**: Register your application with Google to obtain the client ID and client secret. This can be done through the Google Developer Console. 3. **Configure OAuth**: In your Flask application, configure the OAuth client with the credentials obtained from Google. 4. **Create User Model**: Define a user model that will be used to create and update user records in the database. 5. **Implement OAuth Routes**: Implement routes for redirecting to Google's OAuth page and for handling the OAuth callback. 6. **Session Management**: Use `flask-login` to manage user sessions after successful sign-in. Here's a practical proposal for updating the `app.py` file: ```python from flask import Flask, render_template, Response, redirect, url_for from flask_login import LoginManager, current_user, login_user, logout_user, login_required from authlib.integrations.flask_client import OAuth from deepface import DeepFace import cv2 import time import mysql.connector import base64 app = Flask(__name__) app.secret_key = 'your_secret_key' # Replace with a real secret key # Configure Flask-Login login_manager = LoginManager() login_manager.init_app(app) # Configure OAuth oauth = OAuth(app) google = oauth.register( name='google', client_id='your_client_id', # Replace with your client ID client_secret='your_client_secret', # Replace with your client secret access_token_url='https://accounts.google.com/o/oauth2/token', access_token_params=None, authorize_url='https://accounts.google.com/o/oauth2/auth', authorize_params=None, api_base_url='https://www.googleapis.com/oauth2/v1/', client_kwargs={'scope': 'openid profile email'}, ) # MySQL connection configuration mysql_connection = mysql.connector.connect( host="", port="3307", user="root", password="", database="database" ) # Define your User model here (if not already defined) # ... @login_manager.user_loader def load_user(user_id): # Load the user from the database # ... return user @app.route('/login') def login(): redirect_uri = url_for('authorize', _external=True) return google.authorize_redirect(redirect_uri) @app.route('/authorize') def authorize(): token = google.authorize_access_token() resp = google.get('userinfo') user_info = resp.json() # Check if user exists in the database, if not create a new one # ... # Log in the user login_user(user) return redirect('/') @app.route('/logout') @login_required def logout(): logout_user() return redirect('/') # ... rest of your Flask app code ... if __name__ == '__main__': app.run(debug=True) ``` Please note that this is a high-level proposal and assumes you have a User model and user loading logic in place. You will need to fill in the details for user management and database interactions. Additionally, you should secure your application by using environment variables for sensitive information like the secret key, client ID, and client secret, rather than hardcoding them into your source code.