继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

分布式中使用redis进行session共享

千岁不倒翁
关注TA
已关注
手记 362
粉丝 60
获赞 387

摘要

在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 = 400, _msg = "Login err" }, JsonRequestBehavior = JsonRequestBehavior.DenyGet };            }            if (user.Name == "wolfy" && user.Pwd == "12345")            {                Session["user"] = user;                return new JsonResult { Data = new { _code = 200, _msg = "Login Success" }, JsonRequestBehavior = JsonRequestBehavior.DenyGet };            }            else            {                return new JsonResult { Data = new { _code = 400, _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

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP