feat: new login with google

This commit is contained in:
akhdanre 2025-03-01 23:02:53 +07:00
parent e5f86203ff
commit ded387c66a
9 changed files with 102 additions and 21 deletions

View File

@ -0,0 +1,12 @@
MONGO_URI=
FLASK_ENV=
DEBUG=
SECRET_KEY=
GOOGLE_PROJECT_ID=
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GOOGLE_AUHT_URI=
GOOGLE_TOKEN_URI=
GOOGLE_AUTH_PROVIDER_X509_CERT_URL=

View File

@ -20,6 +20,12 @@ def login(auth_controller: AuthController = Provide[Container.auth_controller]):
return auth_controller.login() return auth_controller.login()
@auth_blueprint.route("/login/google", methods=["POST"])
@inject
def google_login(auth_controller: AuthController = Provide[Container.auth_controller]):
return auth_controller.google_login()
@auth_blueprint.route("/logout", methods=["DELETE"]) @auth_blueprint.route("/logout", methods=["DELETE"])
@inject @inject
def logout(auth_controller: AuthController = Provide[Container.auth_controller]): def logout(auth_controller: AuthController = Provide[Container.auth_controller]):

View File

@ -1,18 +1,27 @@
import os
from dotenv import load_dotenv from dotenv import load_dotenv
import os
load_dotenv() # Load environment variables from .env # Load variabel dari file .env
load_dotenv()
class Config: class Config:
MONGO_URI = os.getenv( FLASK_ENV = os.getenv("FLASK_ENV", "development")
"MONGO_URI", "mongodb://localhost:27017/quiz_app" DEBUG = os.getenv("DEBUG", "False").lower() in ("true", "1", "t")
) # Default value if not set
FLASK_ENV = os.getenv("FLASK_ENV", "development") # Default to development SECRET_KEY = os.getenv("SECRET_KEY", "your_secret_key")
MONGO_URI = os.getenv("MONGO_URI", "mongodb://localhost:27017/yourdb")
DEBUG = os.getenv("DEBUG", "True").lower() in [ GOOGLE_PROJECT_ID = os.getenv("GOOGLE_PROJECT_ID")
"true", GOOGLE_CLIENT_ID = os.getenv("GOOGLE_CLIENT_ID")
"1", GOOGLE_CLIENT_SECRET = os.getenv("GOOGLE_CLIENT_SECRET")
"t", GOOGLE_AUTH_URI = os.getenv(
] # Convert string to boolean "GOOGLE_AUTH_URI", "https://accounts.google.com/o/oauth2/auth"
)
GOOGLE_TOKEN_URI = os.getenv(
"GOOGLE_TOKEN_URI", "https://oauth2.googleapis.com/token"
)
GOOGLE_AUTH_PROVIDER_X509_CERT_URL = os.getenv("GOOGLE_AUTH_PROVIDER_X509_CERT_URL")
GOOGLE_SCOPE = "email profile"
GOOGLE_BASE_URL = "https://www.googleapis.com/oauth2/v1/"

View File

@ -5,9 +5,12 @@ from services import AuthService
class AuthController: class AuthController:
def __init__(self, userService: UserService, authService: AuthService): def __init__(
self, userService: UserService, authService: AuthService, googleAuth=None
):
self.user_service = userService self.user_service = userService
self.auth_service = authService self.auth_service = authService
self.google_auth = googleAuth
def login(self): def login(self):
data = request.get_json() data = request.get_json()
@ -17,6 +20,14 @@ class AuthController:
return jsonify(response.to_dict()), 200 return jsonify(response.to_dict()), 200
return jsonify(response.to_dict()), 400 return jsonify(response.to_dict()), 400
def google_login(self):
data = request.get_json()
id_token = data["token"]
response = self.google_auth.parse_id_token(id_token)
if response:
return jsonify({"message": response})
return jsonify({"message": "google login failed"})
def register(self): def register(self):
return jsonify({"message": "register"}) return jsonify({"message": "register"})

View File

@ -5,11 +5,9 @@ from configs import Config
def init_db(app: Flask) -> PyMongo: def init_db(app: Flask) -> PyMongo:
try: try:
app.config["MONGO_URI"] = Config.MONGO_URI mongo = PyMongo(app)
mongo = PyMongo(app) # Initialize PyMongo with the app
print(f"Connecting to MongoDB: {Config.MONGO_URI}")
mongo.cx.server_info() # Ping the MongoDB server mongo.cx.server_info()
print("✅ MongoDB connection successful!") print("✅ MongoDB connection successful!")
return mongo return mongo

View File

@ -9,6 +9,7 @@ class Container(containers.DeclarativeContainer):
"""Dependency Injection Container""" """Dependency Injection Container"""
mongo = providers.Dependency() mongo = providers.Dependency()
google_auth = providers.Dependency()
# repository # repository
user_repository = providers.Factory(UserRepository, mongo.provided.db) user_repository = providers.Factory(UserRepository, mongo.provided.db)
@ -17,4 +18,6 @@ class Container(containers.DeclarativeContainer):
user_service = providers.Factory(UserService, user_repository) user_service = providers.Factory(UserService, user_repository)
# controllers # controllers
auth_controller = providers.Factory(AuthController, user_service, auth_service) auth_controller = providers.Factory(
AuthController, user_service, auth_service, google_auth
)

View File

@ -4,15 +4,33 @@ from configs import Config
from flask import Flask from flask import Flask
from blueprints import auth_blueprint from blueprints import auth_blueprint
from database import init_db from database import init_db
from authlib.integrations.flask_client import OAuth
from flask_login import LoginManager
def createApp() -> Flask: def createApp() -> Flask:
app = Flask(__name__) app = Flask(__name__)
app.config.from_object(Config)
container = Container() container = Container()
app.container = container app.container = container
login_manager = LoginManager(app)
oauth = OAuth(app)
google = oauth.register(
name="google",
client_id=app.config["GOOGLE_CLIENT_ID"],
client_secret=app.config["GOOGLE_CLIENT_SECRET"],
access_token_url=app.config["GOOGLE_TOKEN_URI"],
authorize_url=app.config["GOOGLE_AUTH_URI"],
api_base_url=app.config["GOOGLE_BASE_URL"],
client_kwargs={"scope": "openid email profile"},
)
if google is not None:
container.google_auth.override(google)
mongo = init_db(app) mongo = init_db(app)
if mongo is not None: if mongo is not None:
container.mongo.override(mongo) container.mongo.override(mongo)
@ -22,11 +40,10 @@ def createApp() -> Flask:
# Register Blueprints # Register Blueprints
app.register_blueprint(default_blueprint) app.register_blueprint(default_blueprint)
app.register_blueprint(auth_blueprint, url_prefix="/api") app.register_blueprint(auth_blueprint, url_prefix="/api")
# app.register_blueprint(user_blueprint, url_prefix="/api")
return app return app
if __name__ == "__main__": if __name__ == "__main__":
app = createApp() app = createApp()
app.run(debug=Config.DEBUG) app.run(host="0.0.0.0", debug=Config.DEBUG)

View File

@ -0,0 +1,21 @@
from flask_login import (
LoginManager,
UserMixin,
login_user,
logout_user,
login_required,
current_user,
)
google = oauth.remote_app(
"google",
consumer_key="YOUR_GOOGLE_CLIENT_ID",
consumer_secret="YOUR_GOOGLE_CLIENT_SECRET",
request_token_params={"scope": "email"},
base_url="https://www.googleapis.com/oauth2/v1/",
request_token_url=None,
access_token_method="POST",
access_token_url="https://accounts.google.com/o/oauth2/token",
authorize_url="https://accounts.google.com/o/oauth2/auth",
)

View File

@ -5,4 +5,8 @@ python-dotenv==1.0.1
dependency-injector==4.46.0 dependency-injector==4.46.0
pytest==8.3.4 pytest==8.3.4
pydantic==2.10.6 pydantic==2.10.6
email-validator==2.2.0 email-validator==2.2.0
Flask-Bcrypt==1.0.1
flask-jwt-extended==4.7.1
Flask-Login==0.6.3
authlib==1.5.1