• 使用ASP.NET WEB API 进行 JWT授权登录(二)


    前言

    上一次,简单的普及了一波JWT。现在,接下来是对JWT的具体在项目如何使用的总结。

    开发环境

    电脑系统:WIN10 家庭版

    开发工具:2019 VS

    相关步骤

    创建WEB API

    这不再重复了,如果不知道怎么创建的,请回看以往得文章。

    ASP.NET WebApi 学习与实践系列(1)---如何创建 WebApi

    安装JWT

    选中菜单中的 工具->NuGet包管理器->管理解决方案的NuGet程序包 找到JWT安装包,选中安装的项目,点击安装即可。如下图所示:

    Model层创建实体

    在项目中找到Models文件夹,需要添加以下类:

    AuthInfo.cs

    身份验证信息 模拟JWT的payload。

    using System;
    using System.Collections.Generic;
    
    namespace myJWT.Models
    {
        /// <summary>
        /// 身份验证信息 模拟JWT的payload
        /// </summary>
        public class AuthInfo
        {
            /// <summary>
            /// 用户名
            /// </summary>
            public string UserName { get; set; }
            /// <summary>
            /// 角色
            /// </summary>
            public List<string> Roles { get; set; }
            /// <summary>
            /// 是否管理员
            /// </summary>
            public bool IsAdmin { get; set; }
            /// <summary>
            /// 口令过期时间
            /// </summary>
            public DateTime? ExpiryDateTime { get; set; }
        }
    }
    

    LoginRequest.cs

    登录用户信息。

    namespace myJWT.Models
    {
        /// <summary>
        /// 登录用户信息
        /// </summary>
        public class LoginRequest
        {
            /// <summary>
            /// 用户名
            /// </summary>
            public string UserName { get; set; }
            /// <summary>
            /// 密码
            /// </summary>
            public string Password { get; set; }
        }
    }
    

    TokenInfo.cs

    获取令牌。

    namespace myJWT.Models
    {
        /// <summary>
        /// 获取令牌
        /// </summary>
        public class TokenInfo
        {
            /// <summary>
            /// 是否成功
            /// </summary>
            public bool Success { get; set; }
            /// <summary>
            /// 令牌
            /// </summary>
            public string Token { get; set; }
            /// <summary>
            /// 错误信息
            /// </summary>
            public string Message { get; set; }
        }
    }
    

    创建Token控制器

    Controllers文件夹中,创建一个Token的控制类,根据用户名和密码获取Token信息。如下代码所示:

    using JWT;
    using JWT.Algorithms;
    using JWT.Serializers;
    using myJWT.Models;
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Web.Http;
    
    namespace myJWT.Controllers
    {
        [RoutePrefix("api/Token")]
        public class TokenController : ApiController
        {
            #region 登录
            /// <summary>
            /// 登录
            /// </summary>
            /// <param name="loginRequest"></param>
            /// <returns></returns>
            [HttpPost]
            [Route("Login")]
            public TokenInfo Login([FromBody] LoginRequest loginRequest)
            {
                TokenInfo tokenInfo = new TokenInfo();//需要返回的口令信息
                if (loginRequest != null)
                {
                    string userName = loginRequest.UserName;
                    string passWord = loginRequest.Password;
                    bool isAdmin = (userName == "admin") ? true : false;
                    //模拟数据库数据,真正的数据应该从数据库读取
                    //身份验证信息
                    AuthInfo authInfo = new AuthInfo
                    {
                        UserName = userName,
                        Roles = new List<string> { "admin", "commonrole" },
                        IsAdmin = isAdmin,
                        ExpiryDateTime = DateTime.Now.AddHours(2)
                    };
                    const string secretKey = "GQDstcKsx0NHjPOuXOYg5MbeJ1XT0uFiwDVvVBrk";//口令加密秘钥
                    try
                    {
                        byte[] key = Encoding.UTF8.GetBytes(secretKey);
                        IJwtAlgorithm algorithm = new HMACSHA256Algorithm();//加密方式
                        IJsonSerializer serializer = new JsonNetSerializer();//序列化Json
                        IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();//base64加解密
                        IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);//JWT编码
                        var token = encoder.Encode(authInfo, key);//生成令牌
    
                        
                        //口令信息
                        tokenInfo.Success = true;
                        tokenInfo.Token = token;
                        tokenInfo.Message = "OK";
                    }
                    catch (Exception ex)
                    {
                        tokenInfo.Success = false;
                        tokenInfo.Message = ex.Message.ToString();
                    }
                }
                else
                {
                    tokenInfo.Success = false;
                    tokenInfo.Message = "用户信息为空";
                }
                return tokenInfo;
            } 
            #endregion
        }
    }
    
    

    创建ApiAuthorizeAttribute身份验证

    在项目中创建AuthAttributes文件夹,创建ApiAuthorizeAttribute.cs类,如下代码所示:

    using JWT;
    using JWT.Algorithms;
    using JWT.Serializers;
    using myJWT.Models;
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Web.Http;
    
    namespace myJWT.Controllers
    {
        [RoutePrefix("api/Token")]
        public class TokenController : ApiController
        {
            #region 登录
            /// <summary>
            /// 登录
            /// </summary>
            /// <param name="loginRequest"></param>
            /// <returns></returns>
            [HttpPost]
            [Route("Login")]
            public TokenInfo Login([FromBody] LoginRequest loginRequest)
            {
                TokenInfo tokenInfo = new TokenInfo();//需要返回的口令信息
                if (loginRequest != null)
                {
                    string userName = loginRequest.UserName;
                    string passWord = loginRequest.Password;
                    bool isAdmin = (userName == "admin") ? true : false;
                    //模拟数据库数据,真正的数据应该从数据库读取
                    //身份验证信息
                    AuthInfo authInfo = new AuthInfo
                    {
                        UserName = userName,
                        Roles = new List<string> { "admin", "commonrole" },
                        IsAdmin = isAdmin,
                        ExpiryDateTime = DateTime.Now.AddHours(2)
                    };
                    const string secretKey = "GQDstcKsx0NHjPOuXOYg5MbeJ1XT0uFiwDVvVBrk";//口令加密秘钥
                    try
                    {
                        byte[] key = Encoding.UTF8.GetBytes(secretKey);
                        IJwtAlgorithm algorithm = new HMACSHA256Algorithm();//加密方式
                        IJsonSerializer serializer = new JsonNetSerializer();//序列化Json
                        IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();//base64加解密
                        IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);//JWT编码
                        var token = encoder.Encode(authInfo, key);//生成令牌
    
                        
                        //口令信息
                        tokenInfo.Success = true;
                        tokenInfo.Token = token;
                        tokenInfo.Message = "OK";
                    }
                    catch (Exception ex)
                    {
                        tokenInfo.Success = false;
                        tokenInfo.Message = ex.Message.ToString();
                    }
                }
                else
                {
                    tokenInfo.Success = false;
                    tokenInfo.Message = "用户信息为空";
                }
                return tokenInfo;
            } 
            #endregion
        }
    }
    
    

    创建UserInfo控制器

    Controllers文件夹中,创建一个UserInfo的控制器,用于模拟登录信息。如下代码所示:

    using Newtonsoft.Json;
    using System.Web.Http;
    
    namespace myJWT.Controllers
    {
        [RoutePrefix("api/UserInfo")]
        public class UserInfoController : ApiController
        {
            #region 获取用户信息
            /// <summary>
            /// 获取用户信息
            /// </summary>
            /// <returns></returns>
            [HttpGet]
            [Route("GetUserInfo")]
            [ApiAuthorize]
            public string GetUserInfo()
            {
                var userInfo = new
                {
                    UserName = "test",
                    Tel = "123456789",
                    Address = "testddd"
                };
                return JsonConvert.SerializeObject(userInfo);
            } 
            #endregion
        }
    }
    

    注意:这里需要引用在这之前创建的ApiAuthorize身份验证,不能再使用Authorize。否则,在进行请求的时候会出现已拒绝为请求授权的问题,从而无法请求数据。

    修改Web.Config配置文件

    解决跨域问题。如下图所示:

    应用

    在项目中创建一个TextHtml文件夹,创建一个测试页面textDemo.html页面。用于模拟前端发送请求数据。页面代码如下:

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <title>测试页面</title>
        <link href="../Content/bootstrap.min.css" rel="stylesheet" />
    </head>
    <body>
        <div class="form-horizontal">
            <fieldset style="90%;margin:10px auto;">
                <legend>根据用户名和密码获取Token</legend>
                <div class="form-group">
                    <label for="txtUserName" class="col-sm-2 control-label">登录名称:</label>
                    <div class="col-sm-10">
                        <input type="text" value="" id="txtUserName" class="form-control" placeholder="请输入登录名称" autocomplete="off" />
                    </div>
                </div>
                <div class="form-group">
                    <label for="txtUserPwd" class="col-sm-2 control-label">登录密码:</label>
                    <div class="col-sm-10">
                        <input type="password" value="" id="txtUserPwd" class="form-control" placeholder="请输入登录密码" autocomplete="off" />
                    </div>
                </div>
                <div class="form-group">
                    <div class="col-sm-2 control-label">
    
                    </div>
                    <div class="col-sm-10">
                        <button onclick="login()" class="btn btn-default">登录</button>
                    </div>
                </div>
            </fieldset>
        </div>
    
        <div class="form-horizontal">
            <fieldset style="90%;margin:10px auto;">
                <legend>根据Token获取用户信息</legend>
                <div class="form-group">
                    <label for="txtUserName" class="col-sm-2 control-label">Token:</label>
                    <div class="col-sm-10">
                        <textarea id="txtToken" class="form-control" rows="3"></textarea>
                    </div>
                </div>
                <div class="form-group">
                    <label for="txtUserName" class="col-sm-2 control-label">用户信息:</label>
                    <div class="col-sm-10">
                        <textarea  id="txtUserList" class="form-control" rows="8"></textarea>
                    </div>
                </div>
                <div class="form-group">
                    <div class="col-sm-2 control-label">
    
                    </div>
                    <div class="col-sm-10">
                        <button onclick="GetUseList()" class="btn btn-default">获取</button>
                    </div>
                </div>
            </fieldset>
        </div>
        <script src="../Scripts/jquery-3.4.1.min.js"></script>
        <script src="../Scripts/bootstrap.min.js"></script>
        <script type="text/javascript">
            var m_token = "";
            /*登录获取Token*/
            function login() {
                var m_txtUserName = $("#txtUserName").val();
                var m_txtUserPwd = $("#txtUserPwd").val();
                $.post("https://localhost:44325/api/Token/Login", { UserName: m_txtUserName, Password: m_txtUserPwd }, function (msg) {
                    if (msg.Message == "OK" && msg.Success == true) {
                        m_token = msg.Token;
                        $("#txtToken").val(m_token);
                    }
                });
            }
            /*根据Token获取用户信息*/
            function GetUseList() {
                var m_token = $("#txtToken").val();
                $.ajax({
                    url: "https://localhost:44325/api/UserInfo/GetUserInfo",
                    headers: { "auth": m_token },
                    type: "GET",
                    success: function (msg) {
                        $("#txtUserList").html(msg);
                    }
                });
            }
        </script>
    </body>
    </html>
    

    界面效果如下如所示:

    根据用户名和密码获取Token

    在测试页面,输入用户名和密码,获取Token。如下图所示:

    根据Token获取数据

    通过Ajax``headers中携带Token进行数据请求。如下图所示:

    总结

    以上,就是通过JWT的方式进行的身份授权验证。以上,都是经过实践过后的结果。如果,有不懂得,或者有不妥地方,随时留言。

    原文

  • 相关阅读:
    HDU 1229 还是A+B(A+B陶冶情操)
    WINDOWS API ——CREATETOOLHELP32SNAPSHOT——查找进程
    WinAPI: GetCurrentThread、GetCurrentThreadId、GetCurrentProcess、GetCurrentProcessId
    创建线程后马上CloseHandle(threadhandle)起什么作用
    CloseHandle(),TerminateThread(),ExitThread()的区别
    WinAPI: OpenProcess、GetExitCodeProcess、TerminateProcess (测试强制关闭 OICQ)
    GetVersion和GetVersionEx
    WinAPI: GetModuleFileName、GetModuleHandle
    C# 获取窗口句柄并且关闭应用程序
    IsWindow,findwindow
  • 原文地址:https://www.cnblogs.com/ZengJiaLin/p/14292060.html
Copyright © 2020-2023  润新知