I am trying to use session object with Redis
as the storage in a distributed system in the signin
, signup
and signout
resolvers to set and delete session for userid
but having issues with that because actix' Session
does not implement Send
and cannot be used across threads. It has type: Rc<RefCell<actix_session::SessionInner>>
Question
- What's the idiomatic way to handle such in
async-graphql
? I would like to do something like below:
#[Object]
impl User {
async fn signin(&self, ctx: &Context<'_>) -> anyhow::Result<Vec<User>> {
let session = ctx.data_unchecked::<Session>();
session.insert("user_id", id);
session.get::<UserId>("user_id");
...
}
}
If I try the above, I get:
`Rc<RefCell<actix_session::SessionInner>>` cannot be shared between threads safely
within `actix_session::Session`, the trait `Sync` is not implemented for `Rc<RefCell<actix_session::SessionInner>>`
- Also, where is the right place to create
session
in async-graphql context? I am trying this but would face the same issue:
#[post("/graphql")]
pub async fn index(
schema: web::Data<MyGraphQLSchema>,
req: HttpRequest,
gql_request: GraphQLRequest,
) -> GraphQLResponse {
let mut request = gql_request.into_inner();
let session = req.get_session();
request = request.data(session);
schema.execute(request).await.into()
}
My app:
let redis_key = Key::from(hmac_secret_from_env_var.expose_secret().as_bytes());
App::new()
.wrap(cors)
.wrap(
RedisSession::new(redis.get_url(), redis_key.master())
.cookie_http_only(true)
// allow the cookie only from the current domain
.cookie_same_site(cookie::SameSite::Lax),
)
.wrap(Logger::default())