Is it safe to clone AuthSession? #282
-
|
In order to access #[derive(Clone)]
// This struct is to provide interior mutability to `AuthSession`
// `ctx.data::<T>()` only returns `&T`
pub(crate) struct SharedAuthSession {
// `AuthSession` is from https://docs.rs/axum-login/latest/axum_login/struct.AuthSession.html#
pub(crate) session: Arc<Mutex<AuthSession>>,
}
#[axum::debug_handler]
async fn graphql_handler(
State(schema): State<MainSchema>,
auth_session: crate::users::AuthSession,
req: GraphQLRequest,
) -> GraphQLResponse {
let mut req = req.into_inner();
// attach auth session to the request so that
// resolvers can access it via `ctx.data::<SharedAuthSession>`
req = req.data(crate::users::SharedAuthSession::new(auth_session));
schema.execute(req).await.into()
}
#[Object(name = "UserMutation")]
impl Mutation {
async fn oauth_login<'a>(
&self,
ctx: &Context<'a>,
) -> Option<async_graphql::Result<OauthLoginPayload>> {
// needs a mutable `AuthSession` and obtain one via `SharedAuthSession`
let auth: &SharedAuthSession = ctx.data::<SharedAuthSession>().unwrap();
let mut s: std::sync::MutexGuard<'_, _> = auth.session.lock().unwrap();
s.login(&AuthUser::default()).await.unwrap();
None
}
}And of course it won't work becuase error: future cannot be sent between threads safely
--> crates/graphql/src/data/user.rs:35:1
|
35 | #[Object(name = "UserMutation")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `resolve_field` is not `Send`
|
= help: within `impl std::future::Future<Output = Result<std::option::Option<async_graphql::Value>, ServerError>>`, the trait `std::marker::Send` is not implemented for `std::sync::MutexGuard<'_, axum_login::AuthSession<users::Backend>>`
note: future is not `Send` as this value is used across an await
|
44 | let mut s: std::sync::MutexGuard<'_, _> = auth.session.lock().unwrap();
| ----- has type `std::sync::MutexGuard<'_, axum_login::AuthSession<users::Backend>>` which is not `Send`
45 |
46 | s.login(&AuthUser::default()).await.unwrap();
| ^^^^^ await occurs here, with `mut s` maybe used later
note: required by a bound in `ContainerType::{synthetic#0}`
--> /home/chung/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-graphql-7.0.17/src/resolver_utils/container.rs:38:62
|
38 | ) -> impl Future<Output = ServerResult<Option<Value>>> + Send;
| ^^^^ required by this bound in `ContainerType::{synthetic#0}`To work around this, I just clone the the // vvvvvvvvvvv no longer a MutexGuard
let mut s: AuthSession = auth.session.lock().unwrap().clone;
s.login(&AuthUser::default()).await.unwrap();While it works, I am not sure if I have introduced drawbacks or security flaw. Is it safe to clone AuthSession this way? |
Beta Was this translation helpful? Give feedback.
Answered by
maxcountryman
Aug 4, 2025
Replies: 1 comment 2 replies
-
|
Did you find a way @chungwong ? |
Beta Was this translation helpful? Give feedback.
2 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Please see this PR that was recently merged: #293
I can't speak to GraphQL specifically though as I'm not familiar with that crate and how it works.