using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
namespace Demo04.Models
{
//用户类
public class User
{
[EmailAddress]
[Required]
public string Email { get; set; }
[Required]
public string Password { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Demo04.Models
{
//此类用于规范返回消息
public class Msg
{
public int Code { get; set; } = 200;
public object Data { get; set; }
public string ErrorMsg { get; set; }
}
}
using JWT;
using JWT.Algorithms;
using JWT.Serializers;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Demo04
{
//此类用于Jwt的加密与解密
public class JwtTool
{
//jwt密钥
public static string KEY { get; set; } = "MSGasdjaojOIJOIJJJasdopoPOO";
//加密方法
public static string EnCode(Dictionary<string, object> payload, string key = null)
{
if (string.IsNullOrEmpty(key))
{
key = KEY;
}
//加密过程
IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
IJsonSerializer serializer = new JsonNetSerializer();
IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);
payload.Add("timeout", DateTime.Now.AddDays(1));//添加新键值对用于jwt时间验证
return encoder.Encode(payload, key);//返回加密结果字符串
}
//解密方法
public static Dictionary<string, object> DeCode(string jwtstr, string key = null)
{
if (string.IsNullOrEmpty(key))
{
key = KEY;
}
//解密过程
IJsonSerializer serializer = new JsonNetSerializer();
IDateTimeProvider provider = new UtcDateTimeProvider();
IJwtValidator validator = new JwtValidator(serializer, provider);
IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
var algorithm = new HMACSHA256Algorithm();
IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder, algorithm);
var json = decoder.Decode(jwtstr, key, verify: true);
//反序列成Dictionary<>类型
var result = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
//验证时间
if ((DateTime)result["timeout"]<DateTime.Now)
{
throw new Exception("JWT过期");
}
result.Remove("timeout");//移除时间键值对
return result;
}
}
}
using Demo04.Models.Identity;
using System;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
namespace Demo04.Controllers
{
//此类为自定义的过滤器,继承于Attribute,实现IAuthorizationFilter(授权过滤器)接口
internal class MyValidAttribute : Attribute, IAuthorizationFilter
{
public bool AllowMultiple => throw new NotImplementedException();
public async Task<HttpResponseMessage> ExecuteAuthorizationFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
{
if (actionContext.Request.Headers.TryGetValues("token", out var header))
{
//获得token并存入header
var email = JwtTool.DeCode(header.First())["Email"].ToString();//获得Email键的值
(actionContext.ControllerContext.Controller as ApiController).User = new ApplicationUser(new AuthIdentity(email));//将值存入User.Identity.Name
return await continuation();
}
return new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);//返回未经授权的对应Code
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Web;
namespace Demo04.Models.Identity
{
//若要使用User.Identity,须先实现IPrincipal与IIdentity接口
public class AuthIdentity : IIdentity
{
public AuthIdentity(string name)
{
Name = name;
}
public string Name { get; }
public string AuthenticationType => throw new NotImplementedException();
public bool IsAuthenticated => throw new NotImplementedException();
}
public class ApplicationUser : IPrincipal
{
public ApplicationUser(IIdentity identity)
{
Identity = identity;
}
public IIdentity Identity { get; }
public bool IsInRole(string role)
{
throw new NotImplementedException();
}
}
}
using Demo04.Models;
using Demo04.Models.Identity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
namespace Demo04.Controllers
{
[RoutePrefix("api/user")]
public class UserController : ApiController
{
[HttpPost]
[Route("login")]
public IHttpActionResult Login(User model)
{
if (ModelState.IsValid)//传入参数须先通过过滤器验证
{
//将加密后的登录信息返回给调用者
return Ok(new Msg()
{
//JWT加密
Data = JwtTool.EnCode(new Dictionary<string, object>()
{
{"Email",model.Email }
})
});
}
return Ok(new Msg()
{
Code=500,
ErrorMsg = "参数验证失败"
}) ;
}
[HttpGet]
[MyValid]//调用此方法须在header的token中放入登陆时返回的JWT加密字符串
[Route("info")]
//返回email
public IHttpActionResult GetUserInfo()
{
return Ok(new Msg()
{
Data = ((User.Identity) as AuthIdentity).Name
});
}
}
}
WebAPI通过JWT加密完成登录状态验证using System;using System.Collections.Generic;using System.ComponentModel.DataAnnotations;using System.Linq;using System.Web;namespace Demo04.Models{ //用户类 public class User { [EmailAddress] [Require