jwt登录,获取数据案例

来源:使用ASP.NET WEB API 进行 JWT授权登录(二) - 我是小柒 - 博客园 (cnblogs.com)

相关步骤#

创建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 System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Http.Controllers;
using JWT;
using JWT.Serializers;
using apiToken.Models;
using System.Text;
using System.Net;
using System.Net.Http;

namespace apiToken.AuthAttributes
{
/// <summary>
/// 身份认证拦截器
/// </summary>
public class ApiAuthorizeAttribute: AuthorizeAttribute
{
/// <summary>
/// 指示指定的控件是否已获得授权
/// </summary>
/// <param name="actionContext"></param>
/// <returns></returns>
protected override bool IsAuthorized(HttpActionContext actionContext)
{
//前端请求api时会将token存放在名为"auth"的请求头中
var authHeader = from t in actionContext.Request.Headers where t.Key == "auth" select t.Value.FirstOrDefault();
if (authHeader != null)
{
const string secretKey = "Hello World";//加密秘钥
string token = authHeader.FirstOrDefault();//获取token
if (!string.IsNullOrEmpty(token))
{
try
{
byte[] key = Encoding.UTF8.GetBytes(secretKey);
IJsonSerializer serializer = new JsonNetSerializer();
IDateTimeProvider provider = new UtcDateTimeProvider();
IJwtValidator validator = new JwtValidator(serializer, provider);
IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder);
//解密
var json = decoder.DecodeToObject<AuthInfo>(token, key, verify: true);
if (json != null)
{
//判断口令过期时间
if (json.ExpiryDateTime < DateTime.Now)
{
return false;
}
actionContext.RequestContext.RouteData.Values.Add("auth", json);
return true;
}
return false;
}
catch (Exception ex)
{
return false;
}
}
}
return false;
}

/// <summary>
/// 处理授权失败的请求
/// </summary>
/// <param name="actionContext"></param>
protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
{
var erModel = new
{
Success="false",
ErrorCode="401"
};
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.OK, erModel, "application/json");
}

/// <summary>
/// 为操作授权时调用
/// </summary>
/// <param name="actionContext"></param>
//public override void OnAuthorization(HttpActionContext actionContext)
//{

//}
}
}

 



创建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="width: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="width: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的方式进行的身份授权验证。以上,都是经过实践过后的结果。如果,有不懂得,或者有不妥地方,随时留言。

原文

posted @ 2021-09-15 09:59  vba是最好的语言  阅读(251)  评论(0编辑  收藏  举报