How Lepton Manages GitHub API Authentication and Token Storage: OAuth 2.0 Implementation Guide
Lepton authenticates with GitHub through the standard OAuth 2.0 flow, stores the resulting access token in both Redux state and local Electron JSON storage, and injects the token into the Authorization header for all subsequent API requests.
Lepton is an open-source GitHub Gist client built with Electron that requires secure access to the GitHub API. Understanding how Lepton handles GitHub API authentication and token storage reveals a robust pattern for implementing OAuth 2.0 in desktop applications while maintaining seamless session persistence across restarts.
Initiating the OAuth 2.0 Flow
Opening the Authorization Window
When authentication is required, Lepton calls launchAuthWindow() in app/index.js (lines 79-103). This method creates a new BrowserWindow that loads the GitHub authorization URL constructed using the client credentials stored in configs/account.js (or configs/accountDummy.js during development). The URL includes the client_id and requested scopes, prompting the user to authorize the application through GitHub's standard OAuth interface.
Exchanging the Authorization Code
After the user authorizes the app, GitHub redirects to a callback URL containing a code query parameter. The application extracts this code and invokes the exchange helper:
getGitHubApi(EXCHANGE_ACCESS_TOKEN)(
CONFIG_OPTIONS.client_id,
CONFIG_OPTIONS.client_secret,
code
)
This function, implemented in app/utilities/githubApi/index.js (lines 28-42), sends a POST request to https://github.com/login/oauth/access_token and returns a promise that resolves to an object containing the access_token and associated metadata.
Token Storage Architecture
Redux State Management
Upon successfully receiving the access token, initUserSession(payload.access_token) is called (lines 126-131 in app/index.js). The token is immediately dispatched to the Redux store via the UPDATE_ACCESS_TOKEN action defined in app/actions/index.js (lines 39-44). The reducer_token reducer in app/reducers/reducer_token.js (lines 1-7) updates the application state, making the token available to all components during the active session without repeated disk reads.
Persistent Local Storage
To survive application restarts, Lepton persists the token using Electron's local JSON storage mechanism. The updateLocalStorage function (lines 22-31 in app/index.js) writes both the token and user profile to disk. This dual-storage architecture ensures both fast in-memory access via Redux and long-term persistence via the file system.
Making Authenticated API Requests
Every GitHub API request includes the token in the Authorization header. In app/utilities/githubApi/index.js (lines 44-71), utility functions like getUserProfile, getSingleGist, and requestGists construct request headers as follows:
headers: {
'User-Agent': userAgent,
Authorization: 'token ' + token
}
This consistent pattern ensures all requests are properly authenticated without prompting the user repeatedly, with the token retrieved from the Redux store or passed as an argument to the API helpers.
Restoring Cached Sessions
On application startup, getCachedUserInfo() (lines 38-50 in app/index.js) reads the local JSON storage to check for existing credentials. If a valid token is found, the application bypasses the OAuth login window entirely and calls initUserSession(cached.token) directly (lines 79-85), providing seamless session restoration and immediate access to the user's gists.
Configuration and Client Credentials
OAuth client credentials are configured in configs/account.js (or configs/accountDummy.js for development environments), as referenced in app/index.js (lines 53-60). This modular approach keeps sensitive credentials isolated from the main codebase while allowing environment-specific configurations for production and development builds.
Summary
- Lepton implements OAuth 2.0 using the Authorization Code grant type, opening a
BrowserWindowfor user authorization and exchanging the resulting code for an access token viagetGitHubApi(EXCHANGE_ACCESS_TOKEN)inapp/utilities/githubApi/index.js. - Access tokens are stored in both the Redux store (via the
UPDATE_ACCESS_TOKENaction andreducer_tokenreducer) and local Electron JSON storage (viaupdateLocalStorageinapp/index.js). - All authenticated API requests use the
Authorization: token <access_token>header pattern consistently applied acrossapp/utilities/githubApi/index.js. - Automatic session restoration occurs on startup through
getCachedUserInfo(), which checks for cached tokens before initiating new OAuth flows, ensuring a seamless user experience.
Frequently Asked Questions
Where does Lepton store the GitHub access token?
Lepton stores the token in two locations to balance performance and persistence. The token resides in the Redux store for immediate session access, managed by the reducer_token reducer in app/reducers/reducer_token.js (lines 1-7). Additionally, the token is written to local Electron JSON storage via the updateLocalStorage function in app/index.js (lines 22-31) to maintain authentication across application restarts.
How does Lepton restore the authentication session after closing and reopening?
On application startup, Lepton calls getCachedUserInfo() in app/index.js (lines 38-50) to retrieve the token and profile from local JSON storage. If valid cached credentials exist, the application invokes initUserSession(cached.token) directly (lines 79-85), completely bypassing the OAuth login window and restoring the previous session without user intervention.
What OAuth 2.0 grant type does Lepton use for GitHub authentication?
Lepton implements the standard Authorization Code grant type. The application opens a browser window for the user to authorize the app against GitHub's servers, captures the authorization code from the redirect URL query parameters, and exchanges it for an access token via a POST request to https://github.com/login/oauth/access_token as implemented in app/utilities/githubApi/index.js (lines 28-42).
How is the access token included in GitHub API requests?
The token is included in the Authorization header using the format Authorization: token <access_token>. This header pattern is consistently applied across all GitHub API utility functions in app/utilities/githubApi/index.js (lines 44-71), including getUserProfile and requestGists, ensuring every request is properly authenticated according to GitHub's API specifications.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →