c# asp.net 中使用token验证

 

 

 

 

 

基于token的鉴权机制类似于http协议也是无状态的,它不需要在服务端去保留用户的认证信息或者会话信息。这就意味着基于token认证机制的应用不需要去考虑用户在哪一台服务器登录了,这就为应用的扩展提供了便利。

流程上是这样的:

  • 用户使用用户名密码来请求服务器
  • 服务器进行验证用户的信息
  • 服务器通过验证发送给用户一个token
  • 客户端存储token,并在每次请求时附送上这个token值
  • 服务端验证token值,并返回数据

这个token必须要在每次请求时传递给服务端,它应该保存在请求头里。

OK,按照上述的流程,首先我们应当拿到登录的账户,密码等信息,验证通过后,生成TOKEN并发送给客户端,之后客户端的每个请求只需带上这个TOKEN,服务器端对这个TOKEN验证,验证通过后即可访问服务器资源,。

具体在C#中如何模仿这个流程呢?

  • 用户使用用户名密码来请求服务器
  • 服务器进行验证用户的信息

上述二个步骤其实是个登录过程,在此不作说明!

  • 服务器通过验证发送给用户一个token

发送给客户端一个Token,这个就需要我们生成Token了,那么怎样生成呢?理论模块可参考:Token的组成部分Token存放的信息

 1、用C#生成Token:

首先引入JWT.dll

Token生成的具体代码如下:

View Code--ToKen

2、将生成的Token发送给客户端后,随后,客户端的每次请求只需带上这个Token即可

一般都是将Token存放在Http请求的Headers中,也就是:context.Request.Headers,那么如何接收请求头中的Token呢?接收到Token后如何验证呢?

验证TOKEN时就需要构建 MVC Action 过滤器(AuthorizeAttribute)了,不过在构建 AuthorizeAttribute 之前,有必要对 AuthorizeAttribute 说明下,如下:

首先,AuthorizeAttribute 类位于System.Web.Http 命名空间下及System.Web.Mvc命名空间下,

一般情况下,如果你需要对C# MVC 控制器的访问作认证与授权,你需要用System.Web.Mvc命名空间下的 AuthorizeAttribute ,如果你需要对C# API 控制器的访问作认证与授权,你需要用System.Web.Http 命名空间下的 AuthorizeAttribute !

OK,知道了上述两种不同命名空间下的 AuthorizeAttribute ,下面以范例作为说明:

2.1、自定义MVC ACTION 登录授权验证,(由于本篇博客主讲 Token 的验证与实现,因此,关于MVC 登录验证只做代码说明:

2.1.1、新建一个MVC控制器,命名为BaseController,代码如下:

View Code

2.2.2、新建一个MVC控制器,命名为HomeController,代码如下:

View Code

2.2.3、新建一个登录实体类,命名为:LoginsModel,代码如下:

View Code

2.2.4、修改你的Global.asax文件,修改代码如下:

View Code

2.2.5、公共访问类CommonCS部分代码如下:

View Code

2.2.6、公共Token生成类代码如下:

View Code

2.2.7、新建一个登录页面,Login.cshtml代码如下:

@{
    Layout = null;
}

<!DOCTYPE html>

<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
    
    <title>账户登录</title>
    <link href="~/Content/css/materialize.min.css" rel="stylesheet" />
    <style type="text/css">
    html,
    body {
        height: 100%;
    }
    html {
        display: table;
        margin: auto;
    }
    body {
        display: table-cell;
        vertical-align: middle;
        color:#47c1a8;

    }

    .margin {
      margin: 0 !important;
    }
    
    .card-panel{ min-width:350px;}
    </style>
    <!--[if IE]>
        <script src="http://apps.bdimg.com/libs/html5shiv/3.7/html5shiv.min.js"></script>
    <![endif]-->
</head>
<body class="red">
   
    <div id="login-page" class="row">
        <div class="col s12 z-depth-6 card-panel">
          <form class="login-form">
            <div class="row">
              <div class="input-field col s12 center">
                <img src="/content/images/100.png" alt="" class="responsive-img valign profile-image-login">
                <p class="center login-form-text">账户登录</p>
              </div>
            </div>
            <div class="row margin">
              <div class="input-field col s12">
                <i class="mdi-social-person-outline prefix"></i>
                <input class="validate" id="UserName" name="UserName" type="tel" value="@ViewBag.HX_userName">
                <label for="tel" data-error="wrong" data-success="right" class="center-align">手机号码:</label>
              </div>
            </div>
            <div class="row margin">
              <div class="input-field col s12">
                <i class="mdi-action-lock-outline prefix"></i>
                <input id="UserPwd" name="UserPwd" type="password" value="@ViewBag.HX_userPwd">
                <label for="password">密码:</label>
              </div>
            </div>
            <div class="row">          
              <div class="input-field col s12 m12 l12  login-text">
                  <input type="checkbox" id="remember-me" name="remember-me" />
                  <label for="remember-me">记住我</label>
              </div>
            </div>
            <div class="row">
              <div class="input-field col s12">
                <a href="JavaScript:void(0)" class="btn waves-effect waves-light col s12" onclick="Login()">登 录</a>
              </div>
            </div>
            <div class="row">
               <div class="input-field col s6 m6 l6">
                <p class="margin medium-small"></p>
              </div>
              <div class="input-field col s6 m6 l6">
                  <p class="margin right-align medium-small"><a href="/home/forgotpassword">忘记密码?</a></p>
              </div>          
                </div>
          </form>
        </div>
      </div>
    
    
    <script src="~/Scripts/js/jquery-2.1.0.js"></script>
    <script src="~/Scripts/js/materialize.min.js"></script>
    <script type="text/javascript">
        function Login() {
            var UserName = $("#UserName").val();
            var UserPwd = $("#UserPwd").val();
            var remember = document.getElementById("remember-me").checked;

            $(document).ready(function (data) {
                $.ajax({
                    url: "/Home/UserLogin",
                    type: "post",
                    contentType: "application/json",
                    dataType: "text",
                    data: JSON.stringify({ UserName: UserName, UserPwd: UserPwd, remember: remember }),
                    success: function (result, status) {
                        if (result == "HomeCare.Administrator") {
                            //登录成功 跳转
                            location.href = "/Manger/Index";//管理员登录
                        }
                        else {
                            alert(result);
                        }
                    },
                    error: function (error) {
                        alert(error);
                    }
                });
            });
        }
</script>
      <!--materialize js-->
      
</body>
</html>

 

2.2.8、新建一个登录验证属性,继承自:System.Web.Mvc.AuthorizeAttribute,代码如下:(千呼万唤始出来啊......~_~)

View Code

2.2.9、新建一个MVC 控制器 ,命名为:MangerController,代码如下:

 

上述代码就不做演示了,大致过程是这样的:

Manger/Index的访问权限如下:

登录用户:

 

 

 

上述截图已经很清晰了,不再作重复说明。

OK,上述代码便是整个MVC 控制器 登录验证/授权认证的全部代码。下面我们请出本文终极BOSS,如果接收并解析验证接收的TOKEN。

 3、下面介绍webAPI Controller 的认证授权

3.1、首先,我们自定义一个继承自System.Web.Http 命名空间下的AuthorizeAttribute 属性来解析并验证TOKEN

代码如下:

View Code

3.2、新增一个存储解析Token结果的类,命名为SysHelper.cs,代码如下:

View Code

3.3、公共Token生成方法修改如下:

View Code

3.4、定义一个MVC API Controller 代码如下:

View Code

 

OK,有了上述代码我们就可以模拟TOKEN验证了,模拟步骤如下:/

3.5、模拟TOKEN验证:

3.5.1、生成TOKEN,代码如下:

View Code

生成的TOKEN为:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiLnrb7lj5HogIXkv6Hmga8iLCJpYXQiOjE1MDk2OTEyODQsImV4cCI6MTUwOTY5ODQ4NCwiYXVkIjoiaHR0cDovL2V4YW1wbGUuY29tIiwic3ViIjoiSG9tZUNhcmUuVklQIiwianRpIjoiMjAxNzExMDMwMjQxMTkiLCJVc2VySWQiOjEsIlVzZXJOYW1lIjoiamFjay5jaGVuIiwiVXNlclB3ZCI6ImphY2sxMjM0NTYiLCJVc2VyUm9sZSI6IkhvbWVDYXJlLkFkbWluaXN0cmF0b3IifQ.IryLo19SSghi34LD1PNIOmzgzavQrnmGBD42pdojXtg

3.5.2、将获取的TOKEN(有效期两个小时)返回至客户端,客户端将获取的TOKEN放在 请求头 Headers 中,模拟请求如下(PostMan):

OK,将上述TOKEN随便去掉一个字母,请求结果如下:

过期的TOKEN,请求如下:

 

项目源码位置http://download.csdn.net/download/wolongbb/10102574

 

 内容 参照 @陈卧龙的博客

 

posted @ 2019-04-16 11:05  阿Q啊  阅读(4776)  评论(0编辑  收藏  举报