随着移动互联网的发展,webapi的应用越来越广泛,本文是笔者总结的webapi的认证校验案例,欢迎指出

案例分为两个功能:

  1、用户登录,传入账号和密码到api服务器,然后服务器使用FormsAuthenticationTicket作为身份令牌处理

  2、正式操作数据,传入登录是服务器返回的令牌数据到api服务器,服务器对令牌进行校验返回结果信息

FormsAuthenticationTicket是微软提供给我们开发人员使用,做身份认证使用的,通过认证,我们可以把关键信息存储到服务器。

具体案例

  一、api.html页面,用于测试调用api接口

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta charset="utf-8" />
 5     <title></title>
 6     <script src="Scripts/jquery-1.10.2.min.js"></script>
 7     <script>
 8         function Login() {
 9             alert("数据获取中")
10             $.ajax({
11                 cache: true,
12                 type: "POST",
13                 url: "/api/Account/Login",
14                 data: $('#formLogin').serialize(),// 你的formid
15                 async: false,
16                 beforeSend: function (request) {
17                     request.setRequestHeader("token", $("#token").val());
18                 },
19                 error: function (request) {
20                     alert("Connection error");
21                 },
22                 success: function (data) {
23                     alert("数据获取成功" + data["token"])
24                     $("#token").val(data["token"]);
25 
26                     alert($("#token").val())
27                 }
28             });
29         }
30         function Work() {
31             alert("数据获取中")
32             alert($("#token").val());
33             $.ajax({
34                 cache: true,
35                 type: "POST",
36                 url: "/api/Work/GetData",
37                 data: $('#formWork').serialize(),// 你的formid
38                 async: false,
39                 beforeSend: function (request) {
40                     request.setRequestHeader("token", $("#token").val());
41                 },
42                 error: function (request) {
43                     alert(" ");
44                 },
45                 success: function (data) {
46                     alert("数据获取成功")
47                     alert(data["state"])
48                 }
49             });
50 
51 
52         }
53     </script>
54 </head>
55 <body>
56     <div id="token"></div>
57     登录测试(Account)
58     <form id="formLogin" method="post">
59         <table>
60             <tr><td> loginName: </td><td><input type="text" name="loginName" /></td></tr>
61             <tr><td>password:</td><td><input type="text" name="password" /></td></tr>
62         </table>
63         <input type="button" onclick="Login()" value="登录" />
64     </form>
65     登录测试(Account)
66     <form id="formWork" method="post">
67         <table>
68             <tr><td> loginName: </td><td><input type="text" name="loginName" /></td></tr>
69           
70         </table>
71         <input type="button" onclick="Work()" value="登录" />
72     </form>
73 </body>
74 </html>

二、登录控制器

  

 1 namespace _01WebApi.Controllers
 2 {
 3     public class AccountController : ApiController
 4     {
 5         [AcceptVerbs("POST", "GET")]
 6         public HttpResponseMessage Login([FromBody]GetDataModel getData)
 7         {
 8             HttpResponseMessage result;
 9             string returnValue = "";
10             try
11             { 
12                 //生成票据
13                 string loginName =getData.loginName;
14                 string password = getData.password;
15                 FormsAuthenticationTicket token = new FormsAuthenticationTicket(0, loginName, DateTime.Now,
16                               DateTime.Now.AddHours(1), true, string.Format("{0}&{1}", loginName, password),
17                               FormsAuthentication.FormsCookiePath);
18                 //返回登录结果、用户信息、用户验证票据信息
19                 var Token = FormsAuthentication.Encrypt(token);
20 
21 
22                 File.WriteAllText("d:/loginName" + "_Login.txt", Token);
23 
24                 returnValue = "{\"token\":\"" + Token + "\"}";
25 
26                 result = new HttpResponseMessage { Content = new StringContent(returnValue, Encoding.GetEncoding("UTF-8"), "application/json") };//这里是去掉反斜杠再放回出去,json就只剩下双引号。
27                 return result;
28 
29             }
30             catch (Exception ex)
31             {
32                 returnValue = ex.Message.ToString().Replace("\r", "").Replace("\n", "");
33             }
34             //这里是去掉反斜杠再放回出去,json就只剩下双引号。
35             result = new HttpResponseMessage { Content = new StringContent(CreateMessage(0, returnValue), Encoding.GetEncoding("UTF-8"), "application/json") };
36             return result;
37         }
38         /// <summary>
39         /// 返回参数
40         /// </summary>
41         /// <param name="State">状态 0 失败  1 成功</param>
42         /// <param name="Msg">信息</param>
43         /// <returns></returns>
44         public static string CreateMessage(int State, string Msg)
45         {
46             string str = "{\"state\":\"" + State + "\",\"msg\":\"" + Msg + "\"}";
47             return str;
48         }
49     }
50     public class GetDataModel
51     {
52 
53         public string loginName { get; set; }
54         public string password { get; set; }
55        
56 
57     }
58 
59 }

三、获取数据控制器

 1 namespace _01WebApi.Controllers
 2 {
 3     public class WorkController : ApiController
 4     {
 5         [AcceptVerbs("POST", "GET")]
 6         [SupportFilter]
 7         public HttpResponseMessage GetData([FromBody]GetDataModel getData)
 8         {
 9             HttpResponseMessage result;
10             string returnValue = "";
11             try
12             {
13                 
14                 returnValue = "{\"state\":\"获取数据成功\"}";
15 
16                 result = new HttpResponseMessage { Content = new StringContent(returnValue, Encoding.GetEncoding("UTF-8"), "application/json") };//这里是去掉反斜杠再放回出去,json就只剩下双引号。
17                 return result;
18 
19             }
20             catch (Exception ex)
21             {
22                 returnValue = ex.Message.ToString().Replace("\r", "").Replace("\n", "");
23             }
24             //这里是去掉反斜杠再放回出去,json就只剩下双引号。
25             result = new HttpResponseMessage { Content = new StringContent(CreateMessage(0, returnValue), Encoding.GetEncoding("UTF-8"), "application/json") };
26             return result;
27         }
28         /// <summary>
29         /// 返回参数
30         /// </summary>
31         /// <param name="State">状态 0 失败  1 成功</param>
32         /// <param name="Msg">信息</param>
33         /// <returns></returns>
34         public static string CreateMessage(int State, string Msg)
35         {
36             string str = "{\"state\":\"" + State + "\",\"msg\":\"" + Msg + "\"}";
37             return str;
38         }
39     }
40 }

四、在控制器上增加自定义特性来校验令牌数据

 1 namespace _01WebApi.Common
 2 {
 3     public class SupportFilter : AuthorizeAttribute
 4     {
 5         //重写基类的验证方式,加入我们自定义的Ticket验证
 6         public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
 7 
 8         {
 9             //url获取token
10             var content = actionContext.Request.Properties["MS_HttpContext"] as HttpContextBase;
11             //获取用户提交的token数据,用于和服务器数据进行对比,来判定用户是否有效
12             string token = content.Request.Headers["token"].ToString();
13           
14             if (!string.IsNullOrEmpty(token))
15             {
16                 //解密用户ticket,并校验用户名密码是否匹配
17                 if (ValidateTicket(token))
18                 {
19                     base.IsAuthorized(actionContext);
20                 }
21                 else
22                 {
23                     HandleUnauthorizedRequest(actionContext);
24                 }
25             }
26             //如果取不到身份验证信息,并且不允许匿名访问,则返回未验证401
27             else
28             {
29                 var attributes = actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().OfType<AllowAnonymousAttribute>();
30                 bool isAnonymous = attributes.Any(a => a is AllowAnonymousAttribute);
31                 if (isAnonymous) base.OnAuthorization(actionContext);
32                 else HandleUnauthorizedRequest(actionContext);
33             }
34         }
35 
36         //校验用户名密码(对Session匹配,或数据库数据匹配)
37         private bool ValidateTicket(string encryptToken)
38         {
39             //解密Ticket,并且获取UserData的值
40             var strTicket = FormsAuthentication.Decrypt(encryptToken).UserData;
41 
42             //从Ticket里面获取用户名和密码
43             var index = strTicket.IndexOf("&");
44             string loginName = strTicket.Substring(0, index);
45             string password = strTicket.Substring(index + 1);
46         
47            //获取存储在服务器上面的token数据
48             string token = File.ReadAllText("d:/loginName" + "_Login.txt");
49             if (token == null)
50             {
51                 return false;
52             }
53             //对比服务器中的令牌和传入的是否相等
54             if (token.ToString() == encryptToken)
55             {
56                 return true;
57             }
58 
59             return false;
60 
61         }
62     }
63 }

 

posted on 2018-03-23 19:11  高兴happy  阅读(1082)  评论(0编辑  收藏  举报