>  기사  >  백엔드 개발  >  Asp.net MVC는 knockoutjs를 사용하여 로그인하고 사용자의 내부 및 외부 네트워크 IP와 도시를 기록합니다.

Asp.net MVC는 knockoutjs를 사용하여 로그인하고 사용자의 내부 및 외부 네트워크 IP와 도시를 기록합니다.

高洛峰
高洛峰원래의
2017-02-10 17:21:491479검색

이 글에서는 주로 knockoutjs를 사용해 로그인하고 사용자의 내부 및 외부 네트워크 IP와 도시를 기록하는 Asp.net MVC를 소개합니다(권장). 필요한 친구는

서문

첫 번째 글부터 시작했는데 이제는 로그인부터 시작하고 싶은데

1. MVC 및 Web API의 경로 구성, Web API의 경로 구성은 네임스페이스를 어떻게 지원합니까

2. 필터 구성 방법(보안 확인, 오류 처리 등 구현)

3. 사용자 정의 필터, HttpRouteConstraint, ModelBinder 및 HttpParameterBinding 등

개발 과정에서 이러한 문제가 발생했지만 모든 사항을 너무 많이 언급해야 한다고 생각합니다. 필요한 경우 나중에 다시 확인하세요.

요구사항여전히 동일합니다. 먼저 로그인을 통해 달성하려는 것이 무엇인지 이해해야 합니다.

1. 로그인 페이지(사용자 이름, 비밀번호, 기억하기, 로그인 버튼, 재설정 버튼)

2. 메시지 표시(예: 오류가 발생하면 특정 오류가 표시되고, 로그인하면 로그인이 표시됩니다. 에서 로그인 성공 시 점프 등을 표시합니다.)

3. 로그인 처리(인증, 로그인, 로그인 중 양식 비활성화, 사용자 로그인 시간 및 시간 업데이트, 로그인 기록 추가 등) 사용자의 내부 IP, 외부 IP, 도시, 기타 업무 처리)

4. 점프 성공

효과 달성구현에 앞서 효과 스크린샷을 살펴보겠습니다

로그인 페이지

Asp.net MVC利用knockoutjs实现登陆并记录用户的内外网IP及所在城市점프 페이지

Asp.net MVC利用knockoutjs实现登陆并记录用户的内外网IP及所在城市로그인 재개

Asp.net MVC利用knockoutjs实现登陆并记录用户的内外网IP及所在城市

요구사항 분석 및 구현요구사항은 기본적으로 쉽습니다. 내부 및 외부 네트워크 IP와 로그인 기록이 위치한 도시만 고려하면 됩니다. asp.NET에서 클라이언트의 내부 및 외부 네트워크 IP를 얻는 것은 상당히 번거로운 일이지만, 도시를 얻는 것은 기본적으로 불가능하므로 이를 얻기 위해 타사 API를 사용하는 것을 고려해야 합니다.

1. 내부 IP는 백그라운드에서 직접 획득합니다

2. 외부 IP는 Sina API http://counter.sina.com.cn/ip를 통해 획득할 수 있습니다. 예, 배경은 알 수 없는 이유로 IP만 반환할 수 있습니다

3. 도시는 Baidu API http://api.map.baidu.com/location/ip를 통해 얻습니다. ?ak=&ip인데 이렇게 할 수는 없습니다. 외부 IP를 반환해주기 때문에 둘 다 같이 사용했는데 꽤 고통스러웠습니다.

클라이언트가 해당 API에 액세스할 때 또 다른 도메인 간 문제가 발생합니다. 조사 결과 Baidu API는 크로스 도메인 문제를 잘 해결할 수 있는 JSONP를 지원하지 않는 것으로 나타났습니다. 그러나 변수를 반환하면 페이지 스크립트에 Sina API를 직접 작성하여 해당 변수를 얻을 수 있습니다.

기술도 좋아야 하니까 글을 시작해 보겠습니다.

특정 구현1단계: MVC에서 새 LoginController를 만들고 다음 코드를 추가합니다

using System;
using System.Web.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Zephyr.Core;
using Zephyr.Models;
using Zephyr.Web.Areas.Mms.Common;
namespace Zephyr.Controllers
{
 [AllowAnonymous]
 public class LoginController : Controller
 {
 public ActionResult Index()
 {
 ViewBag.CnName = "建筑材料管理系统";
 ViewBag.EnName = "Engineering Material Mangange System";
 return View();
 }
 }
}

로그인하지 않은 경우에도 액세스할 수 있도록 하려면 클래스에 AllowAnonymous 속성을 사용하여 수정해야 합니다.

2단계: 해당 뷰 추가, ~/Views/Login/Index.cshtml 추가, 코드는 다음과 같습니다

@{
 ViewBag.Title = "登录系统";
 Layout = null;
}
<!doctype html>
<html>
 <head>
 <title>@ViewBag.Title</title>
 <link href="~/Content/css/page/login.css" rel="stylesheet" type="text/css" />
 <script src="~/Content/js/jquery/jquery-1.8.1.min.js"></script>
 <script src="~/Content/js/core/json2.js"></script>
 <script src="~/Content/js/core/knockout-2.2.1.js"></script>
 <script src="~/Content/js/viewModel/login.js"></script>
 <script src="http://counter.sina.com.cn/ip"></script>
 </head>
 <body>
 <p class="second_body">
 <form data-bind="submit:loginClick">
 <p class="logo"><img src="/Content/images/login/logo.png" alt="" /></p>
 <p class="title-zh">@ViewBag.CnName</p>
 <p class="title-en" style="@ViewBag.EnNameStyle">@ViewBag.EnName</p>
 <p class="message" data-bind="html:message"></p>
 <table border="0" style="width:300px;">
  <tr>
  <td style="padding-bottom: 5px;width:55px;">用户名:</td>
  <td colspan="2"><input type="text" class="login" data-bind="value:form.usercode" /></td>
  </tr>
  <tr>
  <td class="lable" style="letter-spacing: 0.5em; vertical-align: middle">密码:</td>
  <td colspan="2"><input type="password" class="login" data-bind="value:form.password" /></td>
  </tr>
  <tr>
  <td></td>
  <td colspan="2"><input type="checkbox" data-bind="checked:form.remember" /><span>系统记住我</span></td>
  </tr>
  <tr>
  <td colspan="3" style="text-align:center">
  <input type="submit" value="登录" class="login_button" />
  <input type="button" value="重置" class="reset_botton" data-bind="click:resetClick" />
  </td>
  </tr>
 </table>
 </form>
 </p>
 </body>
</html>

1 .Script 마지막은 외부 네트워크 IP 정보를 얻기 위한 Sina API를 추가하는 것입니다. 반환하는 데이터 형식은

var ILData = new Array("117.30.94.103","保留地址", "", "", ""); if (typeof(ILData_callback) != "undefined") { ILData_callback(); }

입니다. , 이는 JSONP와 유사하지만 함수 이름이 고정되어 있고 데이터가 전달되지 않습니다. ILData[0]에 직접 액세스하여 외부 네트워크 IP를 얻을 수 있습니다.

2. 위 html의 data-bind=""는 knouckoutjs로 작성되었으며, 이는 viewModel의 속성에 바인딩하는 데 사용됩니다.

3단계: ViewModel 생성

var viewModel = function () {
 var self = this;
 this.form = {
 usercode: ko.observable(),
 password: ko.observable(),
 remember:ko.observable(false),
 ip: null,
 city: null
 };
 this.message = ko.observable();
 this.loginClick = function (form) {
 $.ajax({
 type: "POST",
 url: "/login/doAction",
 data: ko.toJSON(self.form),
 dataType: "json",
 contentType: "application/json",
 success: function (d) {
 if (d.status == &#39;success&#39;) {
  self.message("登陆成功正在跳转,请稍候...");
  window.location.href = &#39;/&#39;;
 } else {
  self.message(d.message);
 }
 },
 error: function (e) {
 self.message(e.responseText);
 },
 beforeSend: function () {
 $(form).find("input").attr("disabled", true);
 self.message("正在登陆处理,请稍候...");
 },
 complete: function () {
 $(form).find("input").attr("disabled", false);
 }
 });
 };
 this.resetClick = function () {
 self.form.usercode("");
 self.form.password("");
 self.form.remember(false);
 };
 this.init = function () {
 self.form.ip = ILData[0];
 $.getJSON("http://api.map.baidu.com/location/ip?ak=F454f8a5efe5e577997931cc01de3974&callback=?", function (d) {
 self.form.city = d.content.address;
 });
 if (top != window) top.window.location = window.location;
 };
 this.init();
};
$(function () { ko.applyBindings(new viewModel());});

viewModel을 정의합니다. 해당 속성에는 양식 정보, 메시지 프롬프트 정보, loginClick 로그인, ResetClick 재설정이 포함됩니다. init 부분은 실제로 viewModel에 배치될 필요가 없습니다.

1. $.getJSON은 callback=? 매개변수가 추가된 JSONP에 대한 액세스입니다. jQuery는 이를 현재 콜백 함수로 자동 처리합니다. 즉, 교차 도메인이 성공한 후에는 자동으로 처리됩니다. 현재 함수를 다시 호출하고 데이터를 전달합니다. 요청된 데이터에서 도시 정보를 받기 위해 viewModel에서 form.city를 사용합니다.

2、最后一句ko.applyBindings(new viewModel())即实现了页面和viewModel的绑定,至此,前台全部完成。接下来写登陆处理doAction,还是放在LoginController中,访问地址为/login/doAction。

第四步:在LoginController中添加doAction的方法返回JSON数据。代码如下:

public JsonResult DoAction(JObject request)
{
 var message = new sys_userService().Login(request);
 return Json(message, JsonRequestBehavior.DenyGet);
}

然后在service层中处理

using System;
using System.Collections.Generic;
using Zephyr.Core;
using System.Dynamic;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using Zephyr.Utils;
using Zephyr.Web.Areas.Mms.Common;
namespace Zephyr.Models
{
 public class sys_userService : ServiceBase<sys_user>
 {
 public object Login(JObject request) 
 {
 var UserCode = request.Value<string>("usercode");
 var Password = request.Value<string>("password");
 //用户名密码检查
 if (String.IsNullOrEmpty(UserCode) || String.IsNullOrEmpty(Password))
 return new { status = "error", message = "用户名或密码不能为空!" };
 //用户名密码验证
 var result = this.GetModel(ParamQuery.Instance()
  .AndWhere("UserCode", UserCode)
  .AndWhere("Password", Password)
  .AndWhere("IsEnable", true));
 if (result == null || String.IsNullOrEmpty(result.UserCode))
 return new { status = "error", message = "用户名或密码不正确!" };
 //调用框架中的登陆机制
 var loginer = new LoginerBase { UserCode = result.UserCode, UserName = result.UserName };
 FormsAuth.SignIn(loginer.UserCode, loginer, 60 * 8); 
 //登陆后处理
 this.UpdateUserLoginCountAndDate(UserCode); //更新用户登陆次数及时间
 this.AppendLoginHistory(request); //添加登陆履历
 MmsService.LoginHandler(request); //MMS系统的其它的业务处理
 //返回登陆成功
 return new { status = "success", message = "登陆成功!" };
 }
 //更新用户登陆次数及时间
 public void UpdateUserLoginCountAndDate(string UserCode)
 {
 db.Sql(@"
update sys_user
set LoginCount = isnull(LoginCount,0) + 1
 ,LastLoginDate = getdate()
where UserCode = @0 "
 , UserCode).Execute();
 }
 //添加登陆履历
 public void AppendLoginHistory(JObject request)
 {
 var lanIP = ZHttp.ClientIP;
 var hostName = ZHttp.IsLanIP(lanIP) ? ZHttp.ClientHostName : string.Empty; //如果是内网就获取,否则出错获取不到,且影响效率
 var UserCode = request.Value<string>("usercode");
 var UserName = MmsHelper.GetUserName();
 var IP = request.Value<string>("ip");
 var City = request.Value<string>("city");
 if (IP != lanIP)
 IP = string.Format("{0}/{1}", IP, lanIP).Trim(&#39;/&#39;).Replace("::1", "localhost");
 var item = new sys_loginHistory();
 item.UserCode = UserCode;
 item.UserName = UserName;
 item.HostName = hostName;
 item.HostIP = IP;
 item.LoginCity = City;
 item.LoginDate = DateTime.Now;
 db.Insert<sys_loginHistory>("sys_loginHistory", item).AutoMap(x => x.ID).Execute();
 }
 }
}

接收参数定义为JObject对象比较方便取得请求数据,数据服务中的GetModel是服务基类中已有的方法,这当中用到了两个函数,一个为UpdateUserLoginCountAndDate为更新用户登陆次数及时间的处理,另一个AppendLoginHistory添加登陆履历。至此已大功告成!

以上所述是小编给大家介绍的Asp.net MVC利用knockoutjs实现登陆并记录用户的内外网IP及所在城市(推荐),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对PHP中文网的支持!

更多Asp.net MVC利用knockoutjs实现登陆并记录用户的内外网IP及所在城市相关文章请关注PHP中文网!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.