开发者社区> 神牛003> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

MVC - 单点登录中间件

简介: 本章将要和大家分享的是一个单点登录中间件,中间件听起来高深其实这里只是吧单点登录要用到的逻辑和处理流程封装成了几个方法而已,默认支持采用redis服务保存session的方式,也可以使用参数Func方法来做自定义session存储操作的方式,就不用我默认提供的redis存储的方法了;要说本章内容的来源,其实是我在以前的ShenNiu.
+关注继续查看

本章将要和大家分享的是一个单点登录中间件,中间件听起来高深其实这里只是吧单点登录要用到的逻辑和处理流程封装成了几个方法而已,默认支持采用redis服务保存session的方式,也可以使用参数Func<>方法来做自定义session存储操作的方式,就不用我默认提供的redis存储的方法了;要说本章内容的来源,其实是我在以前的ShenNiu.MVC管理系统中加入了最近做的调查问卷模块,这个问卷调查和ShenNiu.MVC不是一个站点,但是我的问卷调查系统可定在维护问卷或题目的时候需要登录人的信息,我又不想再单独弄一套账号方面的程序了,所以就采用这种单点登录模式,以此来提供调查问卷的所需要的用户信息,以及为了不久的将来自己写的某个模块也需要管理用户信息的话,就能省略掉用户模块了,不得不说单点登录在此刻发挥的作用之大;本章内容希望大家能够喜欢,也希望各位多多"扫码支持"和"推荐"谢谢!如果您想要和我们交流更多mvc相关信息可以来Ninesky框架作者:洞庭夕照 指定的官方群 428310563交流;

 

» 单点登录验证手画示例图

» ShenNiuApi.SDK封装中间件代码

» 调查问卷系统使用中间件示例

» 推广调查问卷系统

 

下面一步一个脚印的来分享:

» 单点登录验证手画示例图

首先,咋们要做一个简易的单点登录功能,需要明白其执行的流程和运作的原理,这里将图文并茂重点提出我认为关键的地方,先上一幅手工图:

看起来图画的不是很好看,不过我想表达的意思感觉还是表达清楚了;作为一个单点登录验证模块,最主要的流程有:

1. 未登录时:提供统一登录入口=》去数据库验证账号正确性=》存储会话session(这里采用redis存储token和用户登陆信息,利用其数据过期策略充当session会话机制)=》重定向到redirectUrl指定的地址

2. 已登录时:获取站点的cookie存储的sessionId(token)=》调用验证token有效接口=》这里有两种情况(a,b)

    a) 有效token=》获取登录用户的session存储的信息(redis存储的value信息)

    b) 无效token=》返回无效信息,构造登录入口地址

通过上面分析,大致的流程应该很明确了下面我们就来看封装的代码;

 

» ShenNiuApi.SDK封装中间件代码

这里要看的是中间件的3个方法:SsoMiddleWareServer(登录入口操作),SsoMiddleWareClient(Token验证及获取登录信息),SsoMiddleWareLoginOut(注销操作);这里我已经把方法打包放到了nuget上: Install-Package ShenNiuApi.SDK ,只需要下载最新的sdk,就能轻松帮您实现一个单点登录架构,下面来看具体的代码;

SsoMiddleWareServer(登录入口操作):

 1         /// <summary>
 2         /// 单点登录操作 SSOMiddleWare服务端(方法功能:
 3         /// 1.生成sessionId 
 4         /// 2.存储session到redis(60分钟失效)或者自定义sessionStoreFunc方法中 
 5         /// 3.构造带有token的重定向地址)
 6         /// 注:默认采用redis保存session,因此需要在conf中配置ReadAndWritePorts和OnlyReadPorts两个appSettings节点:
 7         /// ReadAndWritePorts在conf中配置格式如:pwd@ip:port,多个使用‘|’隔开       实例:shenniubuxing3@127.0.0.1:6377
 8         /// OnlyReadPorts在conf中配置格式如:pwd@ip:port,多个使用‘|’隔开              实例:shenniubuxing3@127.0.0.1:6377
 9         /// </summary>
10         /// <typeparam name="TUserBaseInfo">存储登录信息的对象</typeparam>
11         /// <param name="userBaseInfo">登录信息</param>
12         /// <param name="redirectUrl">重定向地址(注:格式应为http://或者https://;并经过UrlEncode转码后的地址;如果是同站点下面的话无需http://标记)</param>
13         /// <param name="token">执行方法无误后ref返回唯一的token(注:token生成规则是唯一的tokenKey+guid+时间戳)</param>
14         /// <param name="tokenKey">生成token的Key(默认:666666)</param>
15         /// <param name="sessionStoreFun">自定义session存储方法(提供自定义操作保存session的方法,覆盖默认的reids存储方式)</param>
16         /// <param name="timeOut">60(分钟)</param>
17         /// <returns>追加有token的重定向地址</returns>
18         public string SsoMiddleWareServer<TUserBaseInfo>(TUserBaseInfo userBaseInfo, string redirectUrl, ref string token, string tokenKey = "666666", Func<TUserBaseInfo, bool> sessionStoreFun = null, int timeOut = 60)
19             where TUserBaseInfo : class,new()
20         {
21             var returnUrl = string.Empty;
22             try
23             {
24                 //非空验证  
25                 if (string.IsNullOrWhiteSpace(redirectUrl) || userBaseInfo == null) { return returnUrl; }
26 
27                 //生成Token
28                 token = Md5Extend.GetSidMd5Hash(tokenKey);
29 
30                 // ShenNiuApi默认的Redis存储session
31                 if (sessionStoreFun == null && userBaseInfo != null)
32                 {
33                     if (!CacheRepository.Current(CacheType.RedisCache).SetCache<TUserBaseInfo>(token, userBaseInfo, timeOut, true)) { return returnUrl; }
34                 }
35                 else { if (!sessionStoreFun(userBaseInfo)) { return returnUrl; } }
36 
37                 //通域名站内系统登录
38                 if (!Uri.IsWellFormedUriString(redirectUrl, UriKind.Absolute))
39                 {
40                     returnUrl = redirectUrl;
41                     return returnUrl;
42                 }
43 
44                 #region 解析并构造跳转链接
45                 redirectUrl = HttpUtility.UrlDecode(redirectUrl);
46                 redirectUrl = redirectUrl.TrimEnd('&');
47                 redirectUrl = Regex.Replace(redirectUrl, "(&)?token=[^&]+(&)?", "");
48                 Uri uri = new Uri(redirectUrl);
49                 var queryStr = uri.Query;
50                 redirectUrl += queryStr.Contains('?') ? "" : "?";
51                 redirectUrl += string.IsNullOrWhiteSpace(queryStr.TrimStart('?')) ? "" : "&";
52                 returnUrl = string.Format("{0}token={1}", redirectUrl, token);
53                 #endregion
54             }
55             catch (Exception ex)
56             {
57                 throw new Exception(ex.Message);
58             }
59             finally
60             {
61                 if (string.IsNullOrWhiteSpace(returnUrl)) { token = string.Empty; }
62             }
63             return returnUrl;
64         }

SsoMiddleWareClient(Token验证及获取登录信息):

 1   /// <summary>
 2         /// 单点登录操作 SSOMiddleWare客户端(方法功能:
 3         /// 1.验证客户端是否有sid或者url地址中带有最新的token 
 4         /// 2.获取服务端session的基本信息(注:默认直接读取服务端的redis库,同server方法一样需要配置对应的账号节点ReadAndWritePorts和OnlyReadPorts)
 5         /// 3.重新设置客户端cookie有效期和服务端存储session的有效期)
 6         /// </summary>
 7         /// <typeparam name="TUserBaseInfo">登陆用户信息对象</typeparam>
 8         /// <param name="httpContext">上下文HttpContext</param>
 9         /// <param name="ssoLoginUrl">sso统一登陆入口地址</param>
10         /// <param name="redirectUrl">待重定向的地址</param>
11         /// <param name="userBaseInfo">获取的登陆用户信息</param>
12         /// <param name="token">唯一token(即:sid)</param>
13         /// <param name="getOrsetSessionFun">自定义获取服务端用户信息方法并且同时要满足重新设置新的session有效时间</param>
14         /// <param name="sidName">cookie保存的sid名称</param>
15         /// <param name="timeOut">过期时间</param>
16         /// <returns></returns>
17         public string SsoMiddleWareClient<TUserBaseInfo>(HttpContext httpContext, string ssoLoginUrl, string redirectUrl, ref TUserBaseInfo userBaseInfo, ref string token, Func<string, int, TUserBaseInfo> getAndsetSessionFun = null, string sidName = "sid", int timeOut = 60)
18                where TUserBaseInfo : class,new()
19         {
20             var returnUrl = string.Empty;
21             try
22             {
23                 userBaseInfo = default(TUserBaseInfo);
24                 token = string.Empty;
25                 if (string.IsNullOrWhiteSpace(ssoLoginUrl) || string.IsNullOrWhiteSpace(redirectUrl) || string.IsNullOrWhiteSpace(sidName)) { return returnUrl; }
26 
27                 //设置过期后验证url串 
28                 returnUrl = string.Format("{0}?returnUrl={1}", ssoLoginUrl, HttpUtility.UrlEncode(redirectUrl));
29 
30                 //获取token
31                 var cookie = httpContext.Request.Cookies.Get(sidName);
32                 token = httpContext.Request.Params["token"];
33                 token = string.IsNullOrWhiteSpace(token) ? (cookie == null ? "" : cookie.Value) : token;
34                 if (string.IsNullOrWhiteSpace(token)) { return returnUrl; }
35 
36                 //获取用户基本信息
37                 if (getAndsetSessionFun != null)
38                 {
39                     userBaseInfo = getAndsetSessionFun(token, timeOut);
40                 }
41                 else
42                 {
43                     userBaseInfo = CacheRepository.Current(CacheType.RedisCache).GetCache<TUserBaseInfo>(token, true);
44                 }
45                 if (userBaseInfo == null)
46                 {
47                     //过期cookie,清空
48                     if (cookie != null)
49                     {
50                         cookie.Expires = DateTime.Now.AddDays(-1);
51                         httpContext.Response.SetCookie(cookie);
52                     }
53                     return returnUrl;
54                 }
55 
56                 //cookie被清除,需要重新设置
57                 if (cookie == null)
58                 {
59                     cookie = new HttpCookie(sidName, token);
60                     cookie.Expires = DateTime.Now.AddMinutes(timeOut);
61                     httpContext.Response.AppendCookie(cookie);
62                 }
63                 else
64                 {
65                     //登陆验证都成功后,需要重新设置cookie中的toke失效时间
66                     cookie.Value = token;
67                     cookie.Expires = DateTime.Now.AddMinutes(timeOut);
68                     httpContext.Response.SetCookie(cookie);
69                 }
70 
71                 //设置服务端session的失效时间
72                 if (getAndsetSessionFun == null)
73                 {
74                     CacheRepository.Current(CacheType.RedisCache).AddExpire(token, timeOut);
75                 }
76                 returnUrl = string.Empty;
77             }
78             catch (Exception ex)
79             {
80                 throw new Exception(ex.Message);
81             }
82             finally { if (!string.IsNullOrWhiteSpace(returnUrl)) { token = string.Empty; } }
83             return returnUrl;
84         }

SsoMiddleWareLoginOut(注销操作):

 1  /// <summary>
 2         /// 单点登录操作 SSOMiddleWare 退出登陆
 3         /// </summary>
 4         /// <param name="httpContext">Http向下文</param>
 5         /// <param name="removeSession">自定义移除方法</param>
 6         /// <param name="sidName">cookie保存的sid名称</param>
 7         /// <returns>true或false</returns>
 8         public bool SsoMiddleWareLoginOut(HttpContext httpContext, Func<string, bool> removeSession = null, string sidName = "sid")
 9         {
10             var isfalse = true;
11             try
12             {
13                 if (string.IsNullOrWhiteSpace(sidName)) { sidName = "sid"; }
14 
15                 //获取cookie中的token
16                 var cookie = httpContext.Request.Cookies.Get(sidName);
17                 if (cookie == null) { return isfalse; }
18 
19                 //设置过期cookie(先过期cookie)
20                 var key = cookie.Value;
21                 cookie.Expires = DateTime.Now.AddDays(-1);
22                 httpContext.Response.SetCookie(cookie);
23 
24                 //移除session
25                 if (removeSession != null)
26                 {
27                     isfalse = removeSession(key);
28                 }
29                 else
30                 {
31                     isfalse = CacheRepository.Current(CacheType.RedisCache).Remove(key);
32                 }
33             }
34             catch (Exception ex)
35             {
36 
37                 throw new Exception(ex.Message);
38             }
39             return isfalse;
40         }

每个方法的参数及作用,每行逻辑代码的都有注释,各位不妨研读下;这里要说的是每个方法都默认有操作redis存储session的步骤,因此能够看出此中间件默认采用的是redis服务存储session;

有人会问为什么会这样做,您单点登录难道最底层用的不是接口来操作登录或验证的吗?这里考虑有这样一个实用场景,作为一位中小型公司的员工来说,接触到服务器通常部署了整个公司的站点比如:站点1,站点2...尽管域名不一样但是都在同一台服务器上,再试想下如果用redis来存储session会话,此刻是不是就能认为我这台服务器就具有直接访问redis的读写权限(当然如果redis服务也在这台服务器上的话就更不用说了),那我直接在中间件中嵌入公共操作redis获取session,存储session等操作是不是都没问题,如此这般那我们还需要单独弄一个session(token)验证的api么,没必要的事情(对于单点登录站点和重定向站点而言没必要),因此我就这么干了,嵌入一个默认的redis操作哈哈(不服可以来辨);尽管如此不得不考虑更多的业务场景,万一登录账单和其他站点不在一个服务器(或者说无法直接访问redis呢),这里在3个中间件方法参数中提供了一个Func<>参数,每个方法的Func<>代表额意思有点差别,各位可以看下注释;有了这个自定义Func,中间件就能识别如果客户端有传递此方法,那么以Func为主,没有就采用默认的方式操作redis,这样允许使用者自定义方法扩展了使用者自己认为调用token验证的api或者其他合理的方式,这也保证了方法的通用性。

 

» 调查问卷系统使用中间件示例

下面我将使用真实的实例来使用ShenNiuApi.SDK中的中间件方法,这里例子是在我调查问卷系统中如何使用;首先通过nuget下载 Install-Package ShenNiuApi.SDK 最新的sdk,然后需要在做登录验证的Filter中或者继承Controller的父类中(我这里是后者)添加如下代码:

 1 public class BaseController : Controller
 2     {
 3 
 4         protected StageModel.MoUserData _userData;
 5 
 6         protected override void OnActionExecuting(ActionExecutingContext filterContext)
 7         {
 8 
 9             #region 采用ShenNiuApiClient的SsoClient中间件
10 
11             ShenNiuApi.SDK.ShenNiuApiClient client = new ShenNiuApi.SDK.ShenNiuApiClient();
12 
13             var ssoLogin="http://www.lovexins.com:8081/User/Login";
14             var redirectUrl = filterContext.HttpContext.Request.Url.AbsoluteUri;
15             var token = string.Empty;
16             var returnUrl = client.SsoMiddleWareClient<StageModel.MoUserData>(System.Web.HttpContext.Current, ssoLogin, redirectUrl, ref this._userData, ref token);
17             if (string.IsNullOrWhiteSpace(token) )
18             {
19                 filterContext.Result = new RedirectResult(returnUrl);
20                 return;
21             }
22             #endregion
23         }
24 
25         protected void ShowMsg(string msg)
26         {
27 
28             ModelState.AddModelError(string.Empty, msg);
29         }
30     }

只需要一句 client.SsoMiddleWareClient<StageModel.MoUserData>(System.Web.HttpContext.Current, ssoLogin, redirectUrl, ref this._userData, ref token); 即可完成问卷系统单点登录的验证和获取登录用户的信息,各种解析和设置sid的cookie信息都已经在中间件方法中完成了,是不是极大减少了您的编码量;为了对比下面我直接贴出没有使用SsoMiddleWareClient方法时候的代码量:

 1 protected override void OnActionExecuting(ActionExecutingContext filterContext)
 2         {
 3 
 4 
 5             var returnUrl = filterContext.HttpContext.Request.Url.AbsoluteUri;
 6             returnUrl = HttpUtility.UrlEncode(returnUrl);
 7             // var result = new RedirectResult(string.Format("http://www.lovexins.com:8081/User/Login?returnUrl={0}", returnUrl));
 8             var result = new RedirectResult(string.Format("http://172.16.9.6:4040/User/Login?returnUrl={0}", returnUrl));
 9             var key = "Sid";
10             var timeOut = 30;
11             try
12             {
13                 var cookie = filterContext.HttpContext.Request.Cookies.Get(key);
14                 var token = filterContext.HttpContext.Request.Params["token"];
15                 token = string.IsNullOrWhiteSpace(token) ? (cookie == null ? "" : cookie.Value) : token;
16                 if (string.IsNullOrWhiteSpace(token))
17                 {
18                     filterContext.Result = result;
19                     return;
20                 }
21 
22                 this._userData = CacheRepository.Current(CacheType.RedisCache).GetCache<StageModel.MoUserData>(token, true);
23                 if (this._userData == null && cookie != null)
24                 {
25                     //清空cookie
26                     cookie.Expires = DateTime.Now.AddDays(-1);
27                     filterContext.HttpContext.Response.SetCookie(cookie);
28                     filterContext.Result = result;
29                     return;
30                 }
31                 else if (this._userData == null)
32                 {
33                     filterContext.Result = result;
34                     return;
35                 }
36 
37                 if (cookie == null)
38                 {
39                     cookie = new HttpCookie(key, token);
40                     cookie.Expires = DateTime.Now.AddMinutes(timeOut);
41                     filterContext.HttpContext.Response.AppendCookie(cookie);
42                 }
43                 else
44                 {
45                     cookie.Value = token;
46                     //登陆验证都成功后,需要重新设置cookie中的toke失效时间
47                     cookie.Expires = DateTime.Now.AddMinutes(timeOut);
48                     filterContext.HttpContext.Response.SetCookie(cookie);
49                 }
50 
51                 //设置session失效时间
52                 CacheRepository.Current(CacheType.RedisCache).AddExpire(token, timeOut);
53             }
54             catch (Exception ex)
55             {
56                 filterContext.Result = result;
57                 return;
58             }
59         }
View Code

从代码量看前者简单多了,有人会说了您这不就是弄了一个方法而已嘛,说什么代码量少了哈哈;这不得不说通常咋们哎使用第三方的插件或者类库,这样极大减少了咋们工作量和提升了开发速度的好处,有了ShenNiuApi.SDK您还需要担心什么呢;不过研究里面的具体步骤,逻辑代码我嘶吼非常赞成的;

有了在调查问卷的自定义Controller父类后,咋们还需要有一个登录的地方,这里我新创建的项目Stage.Web,在其登录get请求的Action中增加了如下代码:

 1    #region 采用ShenNiuApiClient的SsoClient中间件
 2 
 3             ShenNiuApi.SDK.ShenNiuApiClient client = new ShenNiuApi.SDK.ShenNiuApiClient();
 4             var ssoLogin = loginUrl;
 5             var redirectUrl = context.Request.Path;
 6 
 7             var token = string.Empty;
 8             t = default(T);
 9             var returnUrl = client.SsoMiddleWareClient<T>(System.Web.HttpContext.Current, ssoLogin, redirectUrl, ref t, ref token, sidName: UserLoginExtend.CookieName);
10             if (string.IsNullOrWhiteSpace(token))
11             {
12                 return new RedirectResult(returnUrl);
13             }
14             return null;
15             #endregion

直接通过中间件提供的 SsoMiddleWareClient 方法获取登录的token并验证是否已经登陆过,如果登录过了直接通过 return new RedirectResult(returnUrl); 重定向到returnUrl的地址中去;如果没有那么进入登录界面,录入账号信息后:

提交登录,进入咋们post的Action中进过数据库对账号匹配成功了,然后直接调用中间件方法来存储session并提供唯一的token值,再进行重定向跳转:

 1  #region 采用ShenNiuApiClient的SsoServer中间件
 2 
 3                     ShenNiuApi.SDK.ShenNiuApiClient client = new ShenNiuApi.SDK.ShenNiuApiClient();
 4 
 5                     var timeOut = 60; //分钟
 6                     var token = string.Empty;
 7                     var redirectUrl = client.SsoMiddleWareServer<StageModel.MoUserData>(userData, returnUrl, ref token, timeOut: timeOut);
 8                     sbLog.AppendFormat("redirectUrl:{0},token:{1},", redirectUrl, token);
 9                     if (string.IsNullOrWhiteSpace(token) || string.IsNullOrWhiteSpace(redirectUrl))
10                     {
11                         //登陆失败
12                         sbLog.Append("登陆失败,");
13                     }
14                     else
15                     {
16                         //写入Sso统一登陆站点的sid到cookie
17                         var cookie = new HttpCookie(UserLoginExtend.CookieName, token);
18                         cookie.Expires = DateTime.Now.AddMinutes(timeOut);
19                         cookie.Domain = Request.Url.Host;
20                         HttpContext.Response.AppendCookie(cookie);
21                     }
22                     var isAddLog = await StageClass._WrigLogAsync(sbLog.ToString());
23                     return new RedirectResult(string.Format("{0}", redirectUrl));
24                     #endregion

到此出sso的代码基本完成了就这么简单,不过这里默认采用的是我嵌入的redis服务来存储session信息的,所以还需要配置一个redis相关账号密码等的节点,这里只需要您在 C:\Conf\ShenNiuApi.xml 磁盘下面增加如下名称的xml文件,文件内容也简单:

 1 <ShenNiuApi>
 2     <RedisCache>
 3         <!--读写权限服务地址,多个使用'|'隔开(格式如:pwd@ip:port)-->
 4         <UserName>shenniubuxing3@111.111.111.152:1111</UserName>
 5         <!--只读权限服务地址,多个使用'|'隔开-->
 6         <UserPwd>shenniubuxing3@111.111.111.152:1111|shenniubuxing3@127.0.0.1:6377</UserPwd>
 7         <ApiUrl></ApiUrl>
 8         <ApiKey></ApiKey>
 9     </RedisCache>
10 </ShenNiuApi>

把内容里面的redis账号,密码,端口,地址改成您自己的就行了;因为是在C盘中所以您服务器的其他站点也能够访问,假如您默认使用redis的方式存储session,那么只需要按照上面步骤就能快速的搭建一个单点登录架构;这里我提供下调查问卷使用单点登录测试的地址:www.lovexins.com:1001/Subject 测试账号:shenniu003 密码:123123,注意登录界面的域名和问卷调查的域名一样,只是端口不一样而已,如果您要看效果可以在浏览器F12,然后如图操作:

能够看到这个sid就是地址栏中的token值,这就是咋们定义的sessionId拉,您不想试试吗。

 

» 推广调查问卷系统

调查问卷我想很多公司都会用到,大家一般都会自己做一套,我这里要为大家推荐的是神牛问卷,具体怎么试用呢,可以登录地址http://www.lovexins.com:8081/User/Login 账号:shenniiu003 密码:123123,进入系统后直接点击“问卷管理”=>"调查问卷",在这里您就可以添加您想调查的问卷信息和选项:

如果您添加完成问卷信息后,可以直接点击“阅览”查看您的问卷展示内容和方式(支持移动手机浏览访问),这也是填写调查问卷的人看到的界面,目前支持的题目类型有(单选,多选,文本输入),测试地址:http://www.lovexins.com:1001/shenniu003/wenjuan7,地址中的shenniu003是根据账号来显示的,如果您是某个企业的hr或者老板这里地址栏可以直接注册成您公司的拼音名称或者汉字(是不是感觉还可以呢):

关键点来了,有了填写的用户咋们需要分析并做统计,这个时候只需要您点击问卷列表中的"统计",就能看到如下名目的图表:

您可以点击某一个问题选项对应的“红色”条,直接进入用户选项的分析报表:

看起来效果还是比较不错的吧,关键有数据统计给老板或者其他朋友看的时候,让人感觉“高大上”,这是选项样式的统计图,那么如果是用户填写类的统计呢,是如下这样的列表:

特点:

1. 富含单选,多选,用户填写类的题目类型

2. 单点登录架构,能快速嵌入到其他系统中

3. 手机web也能访问调查问问卷,问答问题

4. 详细的报表统计

5. 专业的维护人员哈哈

说明:最后要说的是此调查问卷系统是为了方便需要用到此功能的朋友和企业,如果您觉得还可以想发一两个问卷调查内容,可以联系我并让我给您单独分配一个管理者账号,当然如果您是某个企业带头人也想长久使用此调查系统可以联系邮箱:841202396@qq.com,随便您发多少问卷只要符合法定内容;

 

补充:

2017.03.06

应多个博友的需求,这里发送调查问卷源码:ShenNiu.Question(问卷调查-源码包)

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
ESC体验
对ESC使用体验简单分享
5 0
ESC体验
本文为我对ESC体验后的分享,在本文中我描述出了在我部署ESC过程中遇到的困难,以及在我面对困难如何处理这些困难的过程,并且我还对未来工作制定期望,并表达了我在使用ESC获得的收获
31 0
esc使用体验心得
在我看来云服务器有以下优点:省力,不需要专门花时间去维护服务器的硬件,看服务器是否运行正常;稳定,这应该是最主要的有点;安全,做web开发最怕的当然是攻击,所以选择大厂的服务器,自然是最香的;省钱,这当然也是很重要的,尤其对于我们学生用户还是很友好的,爆赞!
16 0
ESC体验
第一部分 自我介绍为主(例如就读的专业,现在几年级等),通过什么方式和途径了解到“飞天加速计划·高校学生在家实践”活动 第二部分 阿里云ECS使用攻略,可记录描写在云服务器使用过程中发现的使用小技巧,分享提高效率的方法或者工具,或者在云服务器ecs使用中遇到了什么问题,通过什么方式解决的。 第三部分 收获总结,展望未来。通过“高校学生在家实践”有哪些收获,或者在使用过程中难忘的瞬间与事件,也可以聊聊自己在这过程中的成长与变化,立足当下,展望未来。
43 0
ESC体验
远程登录ESC部署jar包
151 0
体验esc
初次体验
140 0
+关注
神牛003
技术:学无止境,dota:一生不舍。 感兴趣:Java、shell、Python、netcore、go
87
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载