質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.91%

ASP.netでセッションを維持したいです。

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 377

rainrabbit

score -2

前提・実現したいこと

セッションIDを維持したいです。
(ログイン画面のログイン処理でセッションに保存したユーザIDをその後に続く画面で共有したい)

発生している問題・エラーメッセージ

ログイン時にセッションに保存したユーザIDが、
ログアウトボタン(IMG_BTN_LOG_OUT)をクリックした段階で別のセッションに変わってしまい、
ユーザIDを取得できない状況です。

①ログイン画面と②トップ画面があり、①→②の場合はユーザIDを受渡しできています。
②の画面でボタンクリックをするとセッションIDが変わってしまいます。
①で作ったセッション情報を使ってログアウト処理で行うユーザ管理データベース処理を行いたいです。
(セッションを維持できれば、別の画面でもユーザ情報を使いたいです)

ソースコード

※コントロールボックスの呼び出し元
<%@ Page Title="" Language="C#" MasterPageFile="~/common/base.master" AutoEventWireup="true" CodeFile="Top.aspx.cs" Inherits="Top" %>

<%@ Register Src="~/common/Data.ascx" TagPrefix="uc1" TagName="だたBox" %>
<%@ Register Src="~/common/ControlBox.ascx" TagPrefix="uc1" TagName="ControlBox" %>

<asp:Content ID="CPH_Content1" ContentPlaceHolderID="CPH_Content1" Runat="Server">
   <uc1:ControlBox runat="server" ID="ControlBox" />※今回の質問の対象です
   <uc1:DataBox runat="server" ID="DataBox" />
</asp:Content>

※ControlBox.ascx(コントロールボックスと呼んでいてここにはユーザ名やボタンを配置しています)
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="ControlBox.ascx.cs" Inherits="common_ControlBox" %>
<link href="../css/main.css" rel="stylesheet" type="text/css" />

<!--- ユーザコントロールボックス --->
<div class="controlBox">
    <div class="Name">
        <asp:Label runat="server" ID="LBL_NAME" CssClass="" />
    </div>
    <div class="BtnInner">
        <asp:ImageButton id="IMG_BTN_LOG_OUT"    onclick="BTN_Click" runat="server" ImageUrl="../images/cmd_logout.gif"     class="cmdButton" />&nbsp;
     </div>
</div>

※ControlBox.ascx.cs
public partial class common_ControlBox : System.Web.UI.UserControl
{
    //ページ読み込み初期処理
    protected void Page_Load(object sender, EventArgs e)
    {
        // ポストバック時はリターン(何も処理しない)
        if (IsPostBack == true)    {return;}

        //画面更新毎
        //ログイン画面から遷移したときにはセッションにユーザIDがあることを確認できたました
        //コントロールボックスに配置したボタンをクリックするとセッションからユーザIDはが取得できないので消えてしまうのでポストバック時はリターンの処理をいれました
        refreshDisplay();
    }

        //セッションIDを確認するために追加
    protected void Page_Init(object sender, EventArgs e)
    {
        //★セッションIDが変わってしまうことをブレークポイントを張って確認しました
        Session["SESSION_DATE_NOW"] = DateTime.Now;
    }

    //コントロールボックスのボタン処理
       protected void BTN_Click(object sender, EventArgs e)
    {

        //押下されたボタンによって処理を分岐
        string id = ((ImageButton)sender).ID;
        switch (id)
        {
            case "IMG_BTN_DL":
                //DLボタン押下
                //セッションに保存したユーザIDを次の画面でも利用したいがセッションIDが変わってしまうので取得できない
                Server.TransferRequest("DL.aspx");
                break;

            case "IMG_BTN_LOG_OUT":
                //ログアウトボタン押下
                logout();//★ここでDBからログイン情報を削除したいがログアウトボタンをクリックしたときにはセッションIDが変わってしまう
                break;

            default:
                break;

        }
    }
}

試したこと

ログイン画面のログインボタンの処理を
Server.TransferRequest("top.aspx")から
Response.Redirect("top.aspx")に変更したが、セッションIDが変わってしまいます。

ControlBox.ascxにはユーザ名を表示するLBL_NAMEがありますが、
ログアウトボタンをクリックしたときには空文字になっています。
セッションがだめならhiddon項目にしたラベルからユーザIDを取得を試みましたができず・・・

参考URL
https://ameblo.jp/friskpanda/entry-11364901611.html
http://hensa40.cutegirl.jp/archives/842
https://www.it-swarm.dev/ja/asp.net/aspnet%EF%BC%9A%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E9%96%93%E3%81%AEsessionsessionid%E3%81%AE%E5%A4%89%E6%9B%B4/969626190/
(基本的に、バックエンドでセッションオブジェクトにアクセスしない限り、リクエストごとに新しいsessionIdが生成されます、というのが気になりPage_Initを追加したが効果なし)

検索したワード
ASP C# セッションID 維持
ASP C# セッションID 変わってしまう

【 補足情報】
OS:WindowsServer2012 Standard
Microsoft Visual Studio Enterprise 2019 
C# .net framework 4.5
ASP.net:4.5 Web Forms 
StateServer環境(同一PC)
非MVC環境

私自身は、今回ASPで画面を作るのは初めてです。
元々社内にあるシステムの追加で作ったページなのですが、
セッション管理のない独自仕様のフレームワークでそれならと新規作成しました。
工数的に後戻りできないので、今の作りでセッションを維持したいと考えています。
ほかに必要な情報がありましたら追加しますので、コメントにて教えてください。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • SurferOnWww

    2020/07/02 11:31

    レスが前後してしまったようです・・・が、2020/07/02 11:10 に「早速修正させていたしました」と返事があって、実際に修正したのは 編集 2020/07/02 11:27 と 17 分も後ですよね。そういうことがないように、順番に注意願います。

    キャンセル

  • SurferOnWww

    2020/07/02 12:00 編集

    分からないことが多すぎです。そもそも質問者さんの言う「セッション」とは何かがはっきりしませんが、ASP.NET の HttpSessionState のことと理解して・・・

    > セッションIDを維持したいです。

    「セッションID」はデフォルトではクッキーに含まれますが、毎回の要求でそれが要求ヘッダに含まれていますか? 「セッションID」とセッションの中身の情報は異なることは認識してますか?

    > ログイン時にセッションに保存したユーザIDが、

    「セッションに保存したユーザID」というのはクッキーに含まれる「セッションID」とな別物なのですが、そこのところは分かってますか? 「セッションID」と「セッションに保存したユーザID」は具体的にどのように確認していますか?

    > ログアウトボタン(IMG_BTN_LOG_OUT)をクリックした段階で別のセッションに変わってしまい、
    ユーザIDを取得できない状況です。

    上記の操作でセッションに対してはどのような操作を行っていますか? セッション情報を廃棄していたら(ログアウトという言葉からそうしているのではないかと想像)、当然その後は「セッションに保存したユーザID」は取得できませんけど。

    ただし、クッキーの「セッションID」は変わらず、同じものが使われ続けますが。

    キャンセル

  • rainrabbit

    2020/07/02 12:05

    こちらの手違いで申訳ありませんでした。修正したつもりでしたが、修正時に訂正内容を記入する項目があることに気付かずできたつもりでいました。その後にコメントを確認するときに気付いて修正をしたことで、ご迷惑をお掛けしてしまいました。

    キャンセル

回答 2

+1

質問者さんはどこかに行ってしまったようで、質問のコメントに対するフィードバックがなく、何をしているのかよく分かりませんが、可能性が高そうと思うことを回答しておきます。

違ったらどこがどう違うのかをフィードバックしてください。

ログイン時にセッションに保存したユーザIDが、ログアウトボタン(IMG_BTN_LOG_OUT)をクリックした段階で別のセッションに変わってしまい、ユーザIDを取得できない状況です。

まず、質問者さんの言う「セッション」というのは、ASP.NET の HttpSessionState のことと理解します。

そして、ログイン画面でユーザーがログインに成功すると認証チケット(のようなもの?)をセッションに保存し、セッションクッキー(セッション ID を含む)を発行。これ以降ユーザーがアクセスして来た際は要求ヘッダにセッションクッキーが含まれるので、セッションから認証チケットを取得してログイン中であるかどうかを判断する・・・というようなことをしているのであろうと想像してます。

その想像が当たっているとすると、ログイン中なのかログアウトしているのかの状態が判断できるのはセッションに保存された認証チケットしかないと思うのですが(セッション ID とかセッションクッキーではなくて)、違いますか?

で、「ログアウトボタン(IMG_BTN_LOG_OUT)をクリック」でログアウトしたと見なすのですよね。であれば、ボタンクリックで認証チケットを廃棄または書き換えているということになるはず。そのあたりを調べてみてはいかがですか?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/02 18:12

    SurferOnWwwさん、返信ありがとうございました!
    また、返信が遅くなりご心配をおかけしました。申しわございませんでした。
    (会社の関係で、確認と返信に時間がかかりました。)

    教えていただいた内容を元に自分なりに調査を進めているところです。
    System.Web.SessionState.HttpSessionStateで現在実装を進めています。
    セッションIDはSession.SessionID、ユーザIDはSession["SESSION_USER_ID"]でそれぞれの値を確認しています。

    ログアウトの処理は、これから実装に着手するところでおっしゃる通りセッションの破棄とDB上でのログイン管理をする予定です。

    >「セッションID」はデフォルトではクッキーに含まれますが、毎回の要求でそれが要求ヘッダに含まれ
    >ていますか? 「セッションID」とセッションの中身の情報は異なることは認識してますか?
    今回初めてセッションを使うので、このあたりの認識が薄いと思っています。
    参考URLの中でCromeデベロッパーツールの中にCookies情報あるということで、
    ログイン後の画面で内容を確認したところ、クッキータブ自体がありませんでした。

    認証チケット案について、私もSurferOnWwwさんを頭の片隅に考えているところでした。
    (ログインIDとセッションIDで多重ログインを防ぎたいと考えていて、思いついたもの)

    Stateserverを使っている人聞いたところ、特別なにもしなくてもブラウザが閉じるまでは
    セッションが維持されると聞きましたが、なぜセッションが毎度新しくなるのかは不明のままです。

    参考URL
    https://www.atmarkit.co.jp/ait/articles/0303/08/news001_2.html
    http://dev.blog.fairway.ne.jp/chrome%E3%83%87%E3%83%99%E3%83%AD%E3%83%83%E3%83%91%E3%83%BC%E3%83%BB%E3%83%84%E3%83%BC%E3%83%AB%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%83%98%E3%83%83%E3%83%80%E3%83%BC%E6%83%85%E5%A0%B1%E3%82%92/

    キャンセル

  • 2020/07/02 18:51

    > (会社の関係で、確認と返信に時間がかかりました。)

    > 今回初めてセッションを使うので、このあたりの認識が薄いと思っています。

    会社の仕事でやっているようですね。であれば、「認識が薄い」部分は会社が教育するとか、上司・先輩に聞くとかできるのではないかと思うのですが・・・


    > 参考URLの中でCromeデベロッパーツールの中にCookies情報あるということで、ログイン後の画面で内容を確認したところ、クッキータブ自体がありませんでした。

    Global.asax に Session_Start ハンドラがあるか、Session State 情報を利用するコード(例えば、Session["Data"] = xxxx;)があると、サーバーは "ASP.NET_SessionId" という名前の Session Cookie を生成し、応答ヘッダに含めてブラウザに送信します。以下のような感じです。

    Set-Cookie: ASP.NET_SessionId=d4rbf5nhk1xpo0qouuciwxgy; path=/; HttpOnly

    それを受けたブラウザは、次の要求からそのセッションクッキーを要求ヘッダに含めて送信します。よく調べてください。

    それがないということですとセッションは使われてないということになります。

    > Stateserverを使っている人聞いたところ、特別なにもしなくてもブラウザが閉じるまではセッションが維持されると聞きましたが、

    セッションが維持されるのではなく、同じセッションクッキーが使われ続けるのです。

    上記の例の通り期限は設定されてないので、一旦クッキーを受け取るとブラウザを閉じない限りクッキーが消滅することはなく、ユーザーが同じドメイン内で閲覧するときには、ブラウザーはクッキーをサーバーに送信し続けます。

    そこはセッションがタイムアウト(sessionState 構成要素の timeout 属性に設定した時間が過ぎたことを意味します。デフォルトで 20 分)しても、コードで破棄しても同じです。

    > なぜセッションが毎度新しくなるのかは不明のままです。

    だから「ログアウトボタン(IMG_BTN_LOG_OUT)をクリック」で書き換えたのではないかと言いましたが、レスを読んでもらってますか? ASP.NET のセッションの仕組みを分かってないようですが、分かってないところで迷走してませんか?

    キャンセル

check解決した方法

-1

SurferOnWwwさん、丁寧に教えてくださりありがとうございました!

ユーザIDを引き継ぐことができましたので解決方法を記載します。
①セッションクッキー確認用にログイン処理の画面遷移直前に以下のコードを入れました。
Response.Cookies["accessUser"]["userId"] = "UID0001";

②ログアウトボタンのボタンイベントにブレークポイントを設定してから、
今回の課題となったトップ画面のログアウトボタンを押します。

③イミディエイトウインドウで、セッションクッキーの値を表示します。
Server.HtmlEncode(Request.Cookies["accessUser"]["userId"]);

④"UID0001"を表示できました。

Cromeデベロッパーツールの中のCookies情報も確認できました。
セッションクッキーを設定しないと、タブすら出ないようです。
イメージ説明

Global.asaxについてはファイルそのものがないので参考URLの手順で追加しました。

    void Session_Start(object sender, EventArgs e)
    {
        // 新規セッションを開始したときに実行するコードです
        if (null != Session) { }//ブレークポイントを張りいつ通るのか確認する

    }


でログアウトボタンを押しても通るのか確認したところ、ブレークされました。
ログアウトボタンを押すとPage_PreInitからボタンイベントへ順番に処理が流れるとのことで、
そのあたりで今回の質問していたセッションIDが変わる現象が起きたのかな、と推測しました。

上司も先輩も経験のない言語で相談相手も限られる中、なんとか目的を達成できる見込みがでました。
多重ログイン防止処理もチケット発行の仕組みを作れば何とかできそうです。

筆末になりますが、SurferOnWwwさんと参考URLの記事を書いて下さった方に感謝して質問を終了いたします。
大変ありがとうございました!

参考URL
https://www.ipentec.com/document/csharp-aspnet-url-routing
http://hensa40.cutegirl.jp/archives/1204

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/03 11:28 編集

    質問者さんの言う「セッション」というのは、ASP.NET の HttpSessionState のことだったのではないのですか? そういう返事だったですよね。

    上の質問者さんの回答にある、

    Response.Cookies["accessUser"]["userId"] = "UID0001";

    は ASP.NET で言うセッションとは何の関係もない普通のクッキーですよ。

    また、

    > Global.asaxについてはファイルそのものがないので参考URLの手順で追加しました。

    というのは何の意味もない、というより余計なことで、セッションは使ってないのに常にセッション状態プロバイダーを動かすという負担を増やしているだけです。例え、ホントに ASP.NET のセッションを使うにしても Glabal.asax でのそういう設定は必要ないです。

    完全に迷走してます。これに「解決した方法」マークを付けるのは間違ってますのでマイナス評価しました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.91%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る