Life Cost uses Google OAuth 2.0 as its only authentication method, powered by Flask-Dance. There is no username/password login, no registration form, and no password-reset flow. Every user who accesses the application must sign in with a Google account, and their profile (name, email, and avatar) is fetched from Google and stored locally on first sign-in.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/akevalion/life_cost/llms.txt
Use this file to discover all available pages before exploring further.
Setting Up Google Cloud Credentials
Create or select a Google Cloud project
Go to the Google Cloud Console and either create a new project (e.g.,
life-cost) or select an existing one from the project dropdown at the top of the page.Enable the required APIs
Navigate to APIs & Services → Library and enable the following APIs for your project:
- Google People API — provides access to user profile information
- Google Identity / OpenID Connect — used for the
openidscope
Create an OAuth 2.0 Client ID credential
Go to APIs & Services → Credentials and click + Create Credentials → OAuth 2.0 Client ID.If this is your first credential in the project you may be prompted to configure the OAuth consent screen first. Fill in the required fields (app name, support email, scopes) and save before proceeding.
Set the application type to Web application
On the credential creation form, select Web application as the application type. Give it a descriptive name (e.g.,
Life Cost Web).Add the authorised redirect URI
Under Authorised redirect URIs, click + Add URI and enter the callback URL that Flask-Dance listens on:For local development this is typically:The path
/login/google/authorized is fixed by Flask-Dance when the Google blueprint is registered with url_prefix="/login".The redirect URI must exactly match what you register here, including the protocol (
http vs https), the hostname, and the port. Even a trailing slash difference will cause Google to reject the callback with a redirect_uri_mismatch error.OAuth Flow Walkthrough
When a user visits Life Cost the following sequence occurs:GET /— The index route checkscurrent_user.is_authenticated. If the user is not logged in, they are redirected to/google_login.GET /google_login— This route checks whether Flask-Dance already holds a valid Google token (google.authorized). If not, it redirects the browser to Google’s OAuth 2.0 authorization endpoint.- Google authorization — The user consents to the requested scopes on Google’s login page and is redirected back to the application.
GET /login/google/authorized— Flask-Dance intercepts this callback, exchanges the authorization code for an access token, stores it in the session, and then calls the handler registered asredirect_to="auth.google_login"(or"google_login"in the standaloneindex.pyentry point).- User record upsert — The handler fetches profile data from the Google userinfo endpoint and creates a new
Userrow if none exists for that email, or locates the existing record to log in. GET /— Flask-Login logs the user in and redirects them to the main dashboard.
OAuth Scopes
The application requests the following scopes when redirecting to Google:| Scope | Purpose |
|---|---|
https://www.googleapis.com/auth/userinfo.email | Read the user’s Google account email address |
https://www.googleapis.com/auth/userinfo.profile | Read the user’s name and profile picture URL |
openid | Standard OpenID Connect identity token |
app/main.py:
What Happens on First Login
When a Google account signs in for the first time (no matchingemail found in the user table), the application:
- Creates a new
Userrecord populated withusername,email, andpicturefrom the Google profile response. - Fetches all existing
Walletrows and appends them to the new user’swalletsrelationship, settinglast_visited_wallet_idto the first wallet found. - Commits the new user and their wallet associations to the database.
- Calls
login_user(user)to start the Flask-Login session.
username and picture are not updated from the Google profile on re-login.
The authorized redirect URI registered in Google Cloud Console must exactly match the URI the app sends during the OAuth flow — including the protocol (
http or https), hostname, port, and path. A mismatch results in a 400: redirect_uri_mismatch error from Google. If you change the domain, port, or switch from HTTP to HTTPS, update the URI in Google Cloud Console as well.