一、创建一个TokenHolder类,定义一个Token属性
public class TokenHolder { public static string Token { get; set; } }
二、在web API 自带的App_Start文件夹下创建一个TokenCheckFilter类
using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Net; using System.Net.Http; using System.Text; using System.Web; using System.Web.Helpers; using System.Web.Http; using System.Web.Http.Controllers; namespace WebApplication1.App_Start { //继承 AuthorizeAttribute 类,创建一个名为 TokenCheckFilter 的特性类 public class TokenCheckFilter : AuthorizeAttribute { //重写 OnAuthorization 方法,实现自定义授权逻辑 public override void OnAuthorization(HttpActionContext actionContext) { //从请求头中获取 TokenValue 参数值 var token = HttpContext.Current.Request.Headers["TokenValue"] ?? ""; //如果 Token 值不为空,则校验 Token 是否有效 if (!string.IsNullOrEmpty(token.ToString())) { if (ValidateTicket(token.ToString())) { base.IsAuthorized(actionContext);//如果 Token 有效,则允许访问 API 接口 } else { HandleUnauthorizedRequest(actionContext);//如果 Token 无效,则返回 403 状态码,并提示错误信息 } } else { //如果 Token 值为空,则判断当前 API 接口是否允许匿名访问 var attributes = actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().OfType<AllowAnonymousAttribute>(); bool isAnonymous = attributes.Any(a => a is AllowAnonymousAttribute); if (isAnonymous) base.OnAuthorization(actionContext); //如果接口不允许匿名访问,则返回 403 状态码,并提示错误信息 else HandleUnauthorizedRequest(actionContext); } } //校验 Token 是否有效的方法 private bool ValidateTicket(string encryptToken) { try { if (encryptToken == TokenHolder.Token)//从 TokenHolder 类中获取保存的 Token 值,进行比较 { return true;//如果 Token 有效,则返回 true } else { return false;//如果 Token 无效,则返回 false } } catch (Exception) { return false;//如果 Token异常,也返回 false } } //重写 HandleUnauthorizedRequest 方法,实现自定义错误返回信息 protected override void HandleUnauthorizedRequest(HttpActionContext filterContext) { base.HandleUnauthorizedRequest(filterContext);//调用父类的 HandleUnauthorizedRequest 方法 var response = filterContext.Response = filterContext.Response ?? new HttpResponseMessage(); //状态码401改为其他状态码来避免被重定向。最合理的是改为403,表示服务器拒绝。 response.StatusCode = HttpStatusCode.Forbidden; var content = new { success = false, ret = -2, errs = "服务端拒绝访问:你没有权限?,或者掉线了?" }; response.Content = new StringContent(Json.Encode(content), Encoding.UTF8, "application/json");//返回 JSON 格式的错误信息 } private int GetUserId() { var username = HttpContext.Current.User.Identity.Name;//从 HttpContext 中获取当前登录用户的用户名 var userid = GetUser(username)?.id;//从 HttpContext 中获取当前登录用户的id return userid ?? 0; } //查询数据库中用户的id和用户名 private User GetUser(string username) { DataSet dataSet = package.sqllog("select * from user where username='" + username + "'"); DataRow row = dataSet.Tables[0].Rows[0]; User user = new User() { id = Convert.ToInt32(row["id"].ToString()), username = row["username"].ToString() }; return user; } public class User { public int id { get; set; } public string username { get; set; } } } }
三、使用Token鉴权过滤器 例:
[HttpGet] [System.Web.Http.Route("api/index/shili")] [TokenCheckFilter] public object get(int x) { int y = 200; int S = x + y; return Json(new { ret = 200, success = true, data = S }); }
四、使用接口时需要在请求头里加入你自定义的Token,然后进行接口访问