diff options
Diffstat (limited to 'src/api/login.rs')
| -rw-r--r-- | src/api/login.rs | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/src/api/login.rs b/src/api/login.rs index de6e390..1907bac 100644 --- a/src/api/login.rs +++ b/src/api/login.rs @@ -54,6 +54,16 @@ pub(crate) struct Token { /// `HttpOnly`, `SameSite=Strict`, so no script and no other site's page sends it. pub(crate) const SESSION_COOKIE: &str = "continuum-token"; +/// Whether the session cookie lets `request` in: one that reads (`GET`, `HEAD`), or +/// renews or ends the session. One that changes anything brings the token itself +/// (`Authorization`), as a page of another site, or of another port of the same host +/// (which a cookie doesn't tell apart), can't make a browser send it. +fn cookie_lets_in(request: &Request<Body>) -> bool { + use axum::http::Method; + let method = request.method(); + method == Method::GET || method == Method::HEAD || request.uri().path() == "/auth/session" +} + /// The session cookie's token, if the request brings one. fn session_cookie(request: &Request<Body>) -> Option<String> { request @@ -70,7 +80,8 @@ fn session_cookie(request: &Request<Body>) -> Option<String> { /// A request with `Authorization: Bearer <token>`: its user is the token's, if this /// node takes it (`token::verify`); `401`, saying why, if not. One without /// `Authorization` but with the session cookie: the cookie's token's, if taken (if not, -/// as if it brought none). Others go on to `auth::basic_auth`. +/// as if it brought none), for reading only (`cookie_lets_in`). Others go on to +/// `auth::basic_auth`. pub(crate) async fn bearer( State(state): State<AppState>, mut request: Request<Body>, @@ -86,7 +97,7 @@ pub(crate) async fn bearer( Some(text) => (text.to_owned(), false), None => return next.run(request).await, }, - None => match session_cookie(&request) { + None => match session_cookie(&request).filter(|_| cookie_lets_in(&request)) { Some(text) => (text, true), None => return next.run(request).await, }, |
