摘要

在asp.net web中,session经常用来存储当前用户信息,或者通过session进行登录权限的验证。如果是一台服务器,session的使用没问题,如果使用nginx等实现反向代理,将站点部署在多台服务器的情况下,有可能出现这样的现象:你登录的时候是在服务器A登录,并且采用的session存储是进程内存储的方式,你在访问其他页面的情况下,nginx有可能将你的请求转发到服务器B,但服务器B进程内并没有保存你的用户信息,在校验权限的时候,会将你重定向到登录页面。

解决方案

首先需要了解asp.net的session几种存储方式,可以在web.config中进行设置。如图所示:

InProc

服务器的Session存储在IIS进程中,当IIS关闭,重启时,这些Session信息就会丢失,但这种模式最大的好处就是性能提高。但也有缺点,伴随着iis重启或应用重启,session将会丢失。

StateServer

此种方式独立于IIS进程,使用此种方式需要在服务器上开启ASP.NET State Service服务。

Off

表示不使用Session功能。

SQLServer

表示将Session存储在SQL Server。

Custom

自定义存储。

在使用Redis存储的时候可以使用nuget中的一个组件。如图所示:

安装成功之后,需要在web.config中生成配置项,根据实际项目进行配置。如图所示:

设置host(redis服务器ip),databaseId(数据库索引),accessKey(账户pwd)信息。

一个例子

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Wolfy.RedisSession.Models; namespace Wolfy.RedisSession.Controllers
{
public class HomeController : Controller
{
// GET: Home
public ActionResult Login()
{
return View();
}
[HttpPost]
public JsonResult Login(UserViewModel user)
{
if (!ModelState.IsValid)
{
return new JsonResult { Data = new { _code = , _msg = "Login err" }, JsonRequestBehavior = JsonRequestBehavior.DenyGet };
}
if (user.Name == "wolfy" && user.Pwd == "")
{
Session["user"] = user;
return new JsonResult { Data = new { _code = , _msg = "Login Success" }, JsonRequestBehavior = JsonRequestBehavior.DenyGet };
}
else
{
return new JsonResult { Data = new { _code = , _msg = "Login err" }, JsonRequestBehavior = JsonRequestBehavior.DenyGet };
}
}
public ActionResult List()
{
UserViewModel user = Session["user"] as UserViewModel;
if (user == null)
{
return new HttpUnauthorizedResult();
}
return View();
}
}
}
@model Wolfy.RedisSession.Models.UserViewModel

@{
Layout = null;
} <!DOCTYPE html> <html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Login</title>
</head>
<body>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken() <div class="form-horizontal">
<h4>UserViewModel</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
</div>
</div> <div class="form-group">
@Html.LabelFor(model => model.Pwd, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Pwd, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Pwd, "", new { @class = "text-danger" })
</div>
</div> <div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Login" class="btn btn-default" />
</div>
</div>
</div>
} <div>
@Html.ActionLink("Back to List", "Index")
</div>
</body>
</html>

上面的代码片段很简单,登录成功后将用户信息保存在session["user"]中,在访问List视图的时候,需要进行是否登录的验证。如果session为空,则返回未授权,否则向用户展示list视图。

如果在没登录直接访问list,如图所示:

登录

刷新list页面,就可以正常访问了。

看一下redis中保存的内容

我们都知道,在没禁用cookie的情况下,session_id是存储在cookie中的,那么我们看一下请求中的sessionid跟redis的key是否有关系?

看来Redis中用来保存session的键是根据Session_id来生成的。感兴趣的可以研究一下这个开源项目:

https://github.com/Azure/aspnet-redis-providers

分布式中使用redis进行session共享的更多相关文章

  1. 分布式中使用Redis实现Session共享(二)

    上一篇介绍了一些redis的安装及使用步骤,本篇开始将介绍redis的实际应用场景,先从最常见的session开始,刚好也重新学习一遍session的实现原理.在阅读之前假设你已经会使用nginx+i ...

  2. [转]分布式中使用Redis实现Session共享(二)

    本文转自:http://www.cnblogs.com/yanweidie/p/4678095.html 上一篇介绍了一些redis的安装及使用步骤,本篇开始将介绍redis的实际应用场景,先从最常见 ...

  3. (转)分布式中使用Redis实现Session共享(二)

    上一篇介绍了一些redis的安装及使用步骤,本篇开始将介绍redis的实际应用场景,先从最常见的session开始,刚好也重新学习一遍session的实现原理.在阅读之前假设你已经会使用nginx+i ...

  4. 分布式中使用Redis实现Session共享(一)

    上一篇介绍了如何使用nginx+iis部署一个简单的分布式系统,文章结尾留下了几个问题,其中一个是"如何解决多站点下Session共享".这篇文章将会介绍如何使用Redis,下一篇 ...

  5. 分布式中使用Redis实现Session共享(转)

    上一篇介绍了如何使用nginx+iis部署一个简单的分布式系统,文章结尾留下了几个问题,其中一个是"如何解决多站点下Session共享".这篇文章将会介绍如何使用Redis,下一篇 ...

  6. (转)分布式中使用Redis实现Session共享(一)

    上一篇介绍了如何使用nginx+iis部署一个简单的分布式系统,文章结尾留下了几个问题,其中一个是"如何解决多站点下Session共享".这篇文章将会介绍如何使用Redis,下一篇 ...

  7. 项目分布式部署那些事(1):ONS消息队列、基于Redis的Session共享,开源共享

    因业务发展需要现在的系统不足以支撑现在的用户量,于是我们在一周之前着手项目的性能优化与分布式部署的相关动作. 概况 现在的系统是基于RabbitHub(一套开源的开发时框架)和Rabbit.WeiXi ...

  8. 分布式Session共享(一):tomcat+redis实现session共享

    一.前言 本文主要测试redis实现session共享的实现方式,不讨论如何让nginx参与实现负载均衡等. 二.环境配置 本测试在Window下进行 name version port Tomcat ...

  9. spring boot + redis 实现session共享

    这次带来的是spring boot + redis 实现session共享的教程. 在spring boot的文档中,告诉我们添加@EnableRedisHttpSession来开启spring se ...

随机推荐

  1. #NodeJS 服务器基本模板

    基本server配置 cookie / session / get数据 / post数据 / 请求方法 const express=require('express'); const static=r ...

  2. 【转】Android开启网络调试的方法

    方法是偶然看到的: Android 终端adbd服务需要开启5555号端口来建立于adb的连接,如果未开启5555端口,则不能通过网络调试 查看是否可以网络调试: # netstat Android ...

  3. SRILM语言模型格式解读

    先看一下语言模型的输出格式 \data\ ngram = ngram = ngram = \-grams: -5.24036 'cause -0.2084827 -4.675221 'em -0.22 ...

  4. 【LOJ】#2063. 「HAOI2016」字符合并

    题解 dp[i][j][S]表示区间[i,j]内剩余的数位状压后为S的最大值 这样转移起来不就是\(n^3 2^8\)了吗 冷静一下,我们可以发现一段区间内剩下的数位的个数是一定的,也就是我们可以在枚 ...

  5. 【LOJ】#2670. 「NOI2012」随机数生成器

    题解 矩阵乘法,注意需要快速乘 矩阵2*2 a c 0 1 代码 #include <iostream> #include <algorithm> #include <c ...

  6. Educational Codeforces Round 45 (Rated for Div. 2) G - GCD Counting

    G - GCD Counting 思路:我猜测了一下gcd的个数不会很多,然后我就用dfs回溯的时候用map暴力合并就好啦. 终判被卡了MLE.....  需要每次清空一下子树的map... #inc ...

  7. 转:springboot(二):web综合开发

    web开发 spring boot web开发非常的简单,其中包括常用的json输出.filters.property.log等 json 接口开发 在以前的spring 开发的时候需要我们提供jso ...

  8. JVM快速入门

    最近开始了全面的JAVA生态环境学习,因此,JVM的学习是必不可少的一个环节.和.NET的CLR一样,一起的JAVA应用均跑在JVM虚拟机上,不过相对我们只能干看看的CLR,JVM有很大的灵活性,可以 ...

  9. 命令:which、whereis、who和w

    开始 命令搜索的顺序 在shell function中查找,有则调用,无则下一步: 判断命令是否为bash内置命令,有则调用,无则下一步: 在$PATH中搜索该命令,有则调用,无则报错. 判断命令类型 ...

  10. Java 初相识

    Java是如何出现的呢?这就要回到1991年,那时候随着单片机的发展,出现了很多微型的系统,Sun公司在这个时候就成立的一个项目组,成员就有我们熟知的“Java之父” 詹姆斯·高斯林,起初的目标是为了 ...