Skip to content

Commit d1f1e36

Browse files
authored
Refresh ChatGPT auth token (#2484)
ChatGPT token's live for only 1 hour. If the session is longer we don't refresh the token. We should get the expiry timestamp and attempt to refresh before it.
1 parent eaae56a commit d1f1e36

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

codex-rs/core/src/client.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,14 @@ impl ModelClient {
252252
.and_then(|v| v.to_str().ok())
253253
.and_then(|s| s.parse::<u64>().ok());
254254

255+
if status == StatusCode::UNAUTHORIZED {
256+
if let Some(a) = auth.as_ref() {
257+
let _ = a.refresh_token().await;
258+
}
259+
// Retry immediately with refreshed credentials.
260+
continue;
261+
}
262+
255263
// The OpenAI Responses endpoint returns structured JSON bodies even for 4xx/5xx
256264
// errors. When we bubble early with only the HTTP status the caller sees an opaque
257265
// "unexpected status 400 Bad Request" which makes debugging nearly impossible.

codex-rs/login/src/lib.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,39 @@ impl CodexAuth {
6262
}
6363
}
6464

65+
pub async fn refresh_token(&self) -> Result<String, std::io::Error> {
66+
let token_data = self
67+
.get_current_token_data()
68+
.ok_or(std::io::Error::other("Token data is not available."))?;
69+
let token = token_data.refresh_token;
70+
71+
let refresh_response = try_refresh_token(token)
72+
.await
73+
.map_err(std::io::Error::other)?;
74+
75+
let updated = update_tokens(
76+
&self.auth_file,
77+
refresh_response.id_token,
78+
refresh_response.access_token,
79+
refresh_response.refresh_token,
80+
)
81+
.await?;
82+
83+
if let Ok(mut auth_lock) = self.auth_dot_json.lock() {
84+
*auth_lock = Some(updated.clone());
85+
}
86+
87+
let access = match updated.tokens {
88+
Some(t) => t.access_token,
89+
None => {
90+
return Err(std::io::Error::other(
91+
"Token data is not available after refresh.",
92+
));
93+
}
94+
};
95+
Ok(access)
96+
}
97+
6598
/// Loads the available auth information from the auth.json or
6699
/// OPENAI_API_KEY environment variable.
67100
pub fn from_codex_home(

0 commit comments

Comments
 (0)