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"