jlcodes99/cockpit-tools · error
无效的 Auth URL
Error message
无效的 Auth URL
What it means
At the end of get_auth_url (crates/cockpit-core/src/modules/oauth.rs:101) the code parses the hardcoded constant AUTH_URL with url::Url::parse_with_params(...).expect("无效的 Auth URL"). This panics only if the compile-time constant AUTH_URL is not a valid absolute URL. With the shipped Google OAuth endpoint constant this can never fail; the expect is a static-configuration assertion.
Source
Thrown at crates/cockpit-core/src/modules/oauth.rs:101
"https://www.googleapis.com/auth/cclog",
"https://www.googleapis.com/auth/experimentsandconfigs",
]
.join(" ");
let mut params = vec![
("client_id", client_id),
("redirect_uri", redirect_uri),
("response_type", "code"),
("scope", &scopes),
("access_type", "offline"),
("prompt", "consent"),
];
if let Some(state) = state.filter(|value| !value.trim().is_empty()) {
params.push(("state", state));
}
let url = url::Url::parse_with_params(AUTH_URL, ¶ms).expect("无效的 Auth URL");
url.to_string()
}
/// 使用 Authorization Code 交换 Token
pub async fn exchange_code(code: &str, redirect_uri: &str) -> Result<TokenResponse, String> {
crate::modules::logger::log_info(&format!("开始 Token 交换, redirect_uri: {}", redirect_uri));
let client = crate::utils::http::create_client(15);
let (client_id, client_secret, client_key) = oauth_client_config(None)?;
let params = [
("client_id", client_id),
("client_secret", client_secret),
("code", code),
("redirect_uri", redirect_uri),
("grant_type", "authorization_code"),
];
let response = clientView on GitHub (pinned to 1ed8b77992)
Solutions
- Fix the AUTH_URL constant to a valid absolute URL including scheme (e.g. "https://accounts.google.com/o/oauth2/v2/auth").
- Trim and sanitize the constant; verify state/parameter values contain no raw control characters.
- Refactor to return Result<String, String> and map the parse error instead of .expect so misconfiguration surfaces as a normal error.
Example fix
// before
let url = url::Url::parse_with_params(AUTH_URL, ¶ms).expect("无效的 Auth URL");
// after
let url = url::Url::parse_with_params(AUTH_URL, ¶ms)
.map_err(|e| format!("无效的 Auth URL: {e}"))?; Defensive patterns
Strategy: validation
Validate before calling
// Validate AUTH_URL statically before use:
let parsed = url::Url::parse(AUTH_URL);
assert!(parsed.is_ok(), "AUTH_URL must be a valid absolute URL: {:?}", parsed.err()); Type guard
fn is_valid_url(s: &str) -> bool { url::Url::parse(s).map(|u| u.scheme().starts_with("http")).unwrap_or(false) } Try / catch
let url = url::Url::parse_with_params(AUTH_URL, ¶ms)
.map_err(|e| format!("无效的 Auth URL: {e}"))?; Prevention
- Keep AUTH_URL as a compile-time constant and add a unit test parsing it at build/test time.
- Always include the scheme (https://) when changing the endpoint.
- Avoid hand-editing URL constants without running the test suite.
When it happens
Trigger: Panics only when the AUTH_URL constant is edited/typoed to an invalid URL (e.g. missing scheme, illegal characters) or the query parameters contain characters that break URL encoding — none of which occur with the bundled constant.
Common situations: A developer forks the app and points AUTH_URL at a self-hosted or alternate endpoint and mistypes it (missing https://, stray whitespace, invalid IDN), then the panic fires on the first login attempt.
Related errors
- 默认 OAuth client 配置无效
- 解析语言文件失败 {}: {}
- expected launch path must exist
- [Windsurf OAuth] 回调服务恢复失败: login_id={}, error={}
- Claude login start 响应缺少关键字段
AI-assisted analysis of jlcodes99/cockpit-tools@1ed8b77992 (2026-09-05).
Data as JSON: /api/errors/7060388665ebea9c.
Report an issue: GitHub.