# How Lepton Manages GitHub API Authentication and Token Storage: OAuth 2.0 Implementation Guide

> Learn how hackjutsu/Lepton secures GitHub API access using OAuth 2.0. Discover its strategy for authentication, token storage, and request injection.

- Repository: [CosmoX/Lepton](https://github.com/hackjutsu/lepton)
- Tags: how-to-guide
- Published: 2026-02-23

---

**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`](https://github.com/hackjutsu/Lepton/blob/main/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`](https://github.com/hackjutsu/Lepton/blob/main/configs/account.js) (or [`configs/accountDummy.js`](https://github.com/hackjutsu/Lepton/blob/main/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:

```javascript
getGitHubApi(EXCHANGE_ACCESS_TOKEN)(
  CONFIG_OPTIONS.client_id,
  CONFIG_OPTIONS.client_secret,
  code
)

```

This function, implemented in [`app/utilities/githubApi/index.js`](https://github.com/hackjutsu/Lepton/blob/main/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`](https://github.com/hackjutsu/Lepton/blob/main/app/index.js)). The token is immediately dispatched to the Redux store via the `UPDATE_ACCESS_TOKEN` action defined in [`app/actions/index.js`](https://github.com/hackjutsu/Lepton/blob/main/app/actions/index.js) (lines 39-44). The `reducer_token` reducer in [`app/reducers/reducer_token.js`](https://github.com/hackjutsu/Lepton/blob/main/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`](https://github.com/hackjutsu/Lepton/blob/main/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`](https://github.com/hackjutsu/Lepton/blob/main/app/utilities/githubApi/index.js) (lines 44-71), utility functions like `getUserProfile`, `getSingleGist`, and `requestGists` construct request headers as follows:

```javascript
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`](https://github.com/hackjutsu/Lepton/blob/main/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`](https://github.com/hackjutsu/Lepton/blob/main/configs/account.js) (or [`configs/accountDummy.js`](https://github.com/hackjutsu/Lepton/blob/main/configs/accountDummy.js) for development environments), as referenced in [`app/index.js`](https://github.com/hackjutsu/Lepton/blob/main/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 `BrowserWindow` for user authorization and exchanging the resulting code for an access token via `getGitHubApi(EXCHANGE_ACCESS_TOKEN)` in [`app/utilities/githubApi/index.js`](https://github.com/hackjutsu/Lepton/blob/main/app/utilities/githubApi/index.js).
- Access tokens are stored in both the **Redux store** (via the `UPDATE_ACCESS_TOKEN` action and `reducer_token` reducer) and **local Electron JSON storage** (via `updateLocalStorage` in [`app/index.js`](https://github.com/hackjutsu/Lepton/blob/main/app/index.js)).
- All authenticated API requests use the `Authorization: token <access_token>` header pattern consistently applied across [`app/utilities/githubApi/index.js`](https://github.com/hackjutsu/Lepton/blob/main/app/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`](https://github.com/hackjutsu/Lepton/blob/main/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`](https://github.com/hackjutsu/Lepton/blob/main/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`](https://github.com/hackjutsu/Lepton/blob/main/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`](https://github.com/hackjutsu/Lepton/blob/main/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`](https://github.com/hackjutsu/Lepton/blob/main/app/utilities/githubApi/index.js) (lines 44-71), including `getUserProfile` and `requestGists`, ensuring every request is properly authenticated according to GitHub's API specifications.