😎

「actix-web」入門#5 セッション管理

2022/06/05に公開

初めに

セッション管理について記載していく。

以下の説明をしていきます。

  1. セッションの概念
  2. セッションとCookie
  3. フロントエンド側のソース確認&動作確認
  4. バックエンド側のソース確認&動作確認

1. セッションの概念

まず、webにおけるセッションの概念について、確認します。

多分セッションについては、以下のエラーメッセージで触れることが多いと思います。
「ログインセッションが切れました。再度ログインを行ってください。」

セッションの感覚として「画面を開いた際にWebサーバで管理するクライアント情報の単位」を思い浮かべる人は多いと思います。
上記の感覚は、「1セッションで1端末1クライアントの情報を管理する」のが定石だからです。実際には1端末1クライアントの情報でもでもセッションを追加することで複製することが可能です。

要するに、セッションの概略は「Webサーバからみた現在の接続単位」というのが正しいと思います。

2. セッションとCookie

多くのWebエンジニアがセッションと聞くとCokieセッションを思い浮かべると思います。
ブラウザを別セッションで開いて、排他チェックの確認を行うとかが日常茶飯事だからです。

簡単にまとめるとセッションはサーバサイド、Cookieはクライアントサイドです。
さらにCookieはファイルに保存されるものとあくまでメモリでのみ管理されるものに分かれるって感じです。

詳しくは以下のサイトを確認してください。
https://ips.nekotype.com/2441/

3. セッションのソース確認&動作確認

exampleはauthのcookie-sessionを見ていきます。
https://github.com/actix/examples/tree/master/auth/cookie-auth

ソース確認

ソースの構成は「Simple is best!」って感じになってます。

「main.rs」ではルートに対して関数「index」を実行する使用でセッションカウンターが実装されてました。

main.rs
//! Example of cookie based session
//! Session data is stored in cookie, it is limited to 4kb
//!
//! [Redis session example](https://github.com/actix/examples/tree/master/redis-session)
//!
//! [User guide](https://actix.rs/docs/middleware/#user-sessions)

use actix_session::{CookieSession, Session};
use actix_web::{middleware::Logger, web, App, HttpRequest, HttpServer, Result};

/// simple index handler with session
async fn index(session: Session, req: HttpRequest) -> Result<&'static str> {
    log::info!("{:?}", req);

    // RequestSession trait is used for session access
    let mut counter = 1;
    if let Some(count) = session.get::<i32>("counter")? {
        log::info!("SESSION value: {}", count);
        counter = count + 1;
        session.insert("counter", counter)?;
    } else {
        session.insert("counter", counter)?;
    }

    Ok("welcome!")
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    std::env::set_var("RUST_LOG", "actix_web=info");
    env_logger::init();
    log::info!("Starting http server: 127.0.0.1:8080");

    HttpServer::new(|| {
        App::new()
            // enable logger
            .wrap(Logger::default())
            // cookie session middleware
            .wrap(CookieSession::signed(&[0; 32]).secure(false))
            .service(web::resource("/").to(index))
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

ブラウザで確認

画面を開くとこんな感じです。

私の環境だとログがちゃんと出ませんでした。

[2022-06-04T16:38:49Z INFO  actix_web::middleware::logger] 127.0.0.1 "GET / HTTP/1.1" 200 8 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:100.0) Gecko/20100101 Firefox/100.0" 218.147471

なので、直接デバッグでカウンターがカウントアップされているのを確認しました。

4. actix-webのセッションの問題点

3でログに表示されない問題は別途解決するとして、
サーバ再起動時にセッションが引き継がれてしまって驚きました。

3でブラウザ確認後に、サーバ再起動するとリセットされるかと思ったのですが、されなかったです。

あくまでクライアントのCookie情報を頼りにカウントアップしてるみたい…
どういて???セッションとは???

セッションの問題についてまとめてるサイトあったので確認しました。
https://qiita.com/segfo/items/8d992320184fa0a41157

どうやら、actix-webは独自セッションを用意する必要がありそうです。
exampleのauthでもメモリ管理サービス「redis」を使って、ログイン実装してる例あったので次回確認してみようと思います。

次回

「redis-session」を触ってみます。

exampleのwebsocketで独自セッションを扱っているパターンがあったので
「websocket」も扱ってみたい。

上記以降は以下のいずれかをやっていく感じです。
・db周りとかの解説
・test周りとかの解説
・tls周りとかの解説

Discussion