实现原理:

在access_token里加入refresh_token标识,给access_token设置短时间的期限(例如一天),给refresh_token设置长时间的期限(例如七天)。当活动用户(拥有access_token)发起request时,在权限验证里,对于requeset的header包含的access_token、refresh_token分别进行验证:

1、access_token没过期,即通过权限验证;

2、access_token过期,refresh_token没过期,则返回权限验证失败,并在返回的response的header中加入标识状态的key,在request方法的catch中通过webException来获取标识的key,获取新的token(包含新的access_token和refresh_token),再次发起请求,并返回给客户端请求结果以及新的token,再在客户端更新公共静态token模型;

3、access_token过期,refresh_token过期即权限验证失败。

下面展示一下关键代码:

一、登录生成token的时候加入refresh标识

 public TOKEN GetToken(string username, string password)
{
TOKEN token = new TOKEN();
U_USER model = new BLLU_USER().Token(username, password);
if (model != null)
{
string pwd = new SDDMD().MD5_jie(model.USERPWD);
string md5 = new SDDMD().MD5_jia(model.USERID +"&"+ DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") +"&"+ pwd+"&refresh"+ DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
token.access_token = md5;
token.token_type = "Authorization";
token.expires_in = DateTime.Now.ToString("yyyyMMddHHmmss");
//token.refresh_token = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "&refresh";
}
return token;
}

二、在权限验证环节,对于access_token、refresh_token设置不同时间的期限。再根据判断结果返回状态。

        /// <summary>
/// 校验token是否有效
/// </summary>
/// <param name="encryptTicket">用户提交的Token值</param>
/// <returns></returns>
private int ValidateTicket(string encryptTicket)
{
try
{
var strTicket = new DBUtility.SDDMD().MD5_jie(encryptTicket);
string[] TicketMsg = strTicket.Split('&');
if (TicketMsg.Length == )
{
string username = TicketMsg[];//用户名
string passwrod = TicketMsg[];//密码
U_USER model = new BLL.BLLU_USER().Token(username, passwrod);//登陆验证
if (model != null)
{
_userModel = model;
//定义Access_Token有效期为1天,精确到秒
DateTime dt = Convert.ToDateTime(TicketMsg[1]).AddDays(1);
                        //定义Refresh_Token有效期为1天,精确到秒
                        DateTime dtNew= Convert.ToDateTime(TicketMsg[].Substring()).AddDays();//
if (dt > DateTime.Now)
return ; //1:access_token没过期
else
{
if (dtNew > DateTime.Now)
return ; //2:access_token过期,refresh_token没过期
else
return ; //3:access_token过期,refresh_token过期
}
}
else
return ;
}
else
return ;
}
catch { return ; }
}

三、根据反馈的状态执行不同的方法,“2”(access_token过期,refresh_token没过期)状态下,给返回失败的response的header中加入识别的key值。

        /// <summary>
/// 定义Access_token验证过期但Reflesh_token有效返回请求刷新token的信息
/// </summary>
/// <param name="actionContext"></param>
protected void RefreshToken(HttpActionContext actionContext)
{
var content = "refreshtoken";
base.HandleUnauthorizedRequest(actionContext);
var response = actionContext.Response;
response.StatusCode = HttpStatusCode.Forbidden;
response.Content = new StringContent(content, Encoding.UTF8, "application/json");
response.Headers.Add("token", "refresh");//加入识别的key值
}

四、request方法中通过Catch捕获webException对象获取Key值,并获取新的token(包含新的access_token和refresh_token),再次发起请求,并返回给客户端请求结果以及新的token。

        /// <summary>
/// Get head中携带token发送请求
/// </summary>
/// <param name="url">WebAPI访问路径</param>
/// <param name="tokentype">token验证方式 《Authorization》</param>
/// <param name="tokenvalue">token 《"Bearer " + Token》</param>
/// <returns></returns>
public string GetRequest(string url, string tokentype, string tokenvalue)
{
try
{
string responseStr = string.Empty;
WebRequest request = WebRequest.Create(http + url);
request.Timeout = ;
request.Method = "Get";
request.Headers.Add(tokentype, tokenvalue);
var response = request.GetResponse();
Stream ReceiveStream = response.GetResponseStream();
using (StreamReader stream = new StreamReader(ReceiveStream, Encoding.UTF8))
{
responseStr = stream.ReadToEnd();
}
return responseStr;
}
catch (WebException e)
{
using (WebResponse response = e.Response)
{
string result=response.Headers.Get("token");//获取识别的KEY
if (result == "refresh")//验证是否为状态“2”方法所加的key值
{
var strTicket = new SDDMD().MD5_jie(tokenvalue.Substring());
string[] TicketMsg = strTicket.Split('&');
string username = TicketMsg[];//用户名
string passwrod = TicketMsg[];//密码
string responseStr = GetRequest("CYUMS/Token/" + username + "/" + passwrod);//获取新的token
TOKEN tokenmodel = JsonConvert.DeserializeObject<TOKEN>(responseStr);
string secondResponseStr= GetRequest(url, tokenmodel.token_type, "Haval " + tokenmodel.access_token);//再次发起请求
return secondResponseStr + "|" + responseStr;//返回请求结果以及新的token
}
else
throw e;
}
}
}

五、客户端识别token是否更新,如果更新,就更新公共静态token模型中的access_token的值;

            string user = new HttpHelper().GetRequest(getUserModel, tokenmodel.token_type, "Haval " + tokenmodel.access_token);
string[] str = user.Split('|');
if (str.Length == )//判断是否有token更新
{
TOKEN tokens = JsonConvert.DeserializeObject<TOKEN>(str[]);
tokenmodel.access_token = tokens.access_token;
}
U_USER users = JsonConvert.DeserializeObject<U_USER>(str[]);
//business code...

最新文章

  1. Linux下高cpu占有率的调试方案
  2. Java线程:线程的交互
  3. C\C++ sizeof 陷阱&amp;&amp;总结
  4. 并查集(删除) UVA 11987 Almost Union-Find
  5. 加载UI
  6. TortoiseSVN安装使用
  7. C# async await 学习笔记2
  8. unity scroolView 和 groupview
  9. Android常用知识笔记
  10. 2012年7月12 – 腾讯公司 WEB高级应用开发工程师 最新面试题 [转]
  11. iis配置出现的问题及解决
  12. Javascript quiz
  13. [Android开发常见问题-18] Connection to https://dl-ssl.google.com refused
  14. iOS开发tips-UITableView、UICollectionView行高/尺寸自适应
  15. python中的函数对象与闭包函数
  16. javascript基础修炼(3)—What&#39;s this(下)
  17. RabbitMQ快速入门
  18. eclipse 对 hadoop1.2.1 hdfs 文件操作
  19. Python中识别DataFrame中的nan
  20. unity3d API知识点随记

热门文章

  1. 一行命令安装docker和docker-compose(CentOS7)
  2. 读《深入理解Elasticsearch》点滴-查询二次评分
  3. win10下,打开oracle时出现&#160;oracle&#160;initialization&#160;or&#160;shutdown&#160;in&#160;process&#160;错误&#160;的解决办法
  4. 短视频处理LanSoEditor-SDK之功能介绍
  5. 图解Mongo Shell的使用
  6. Vue:获取当前定位城市名
  7. [Machine Learning] Linear regression
  8. JSON说明
  9. SpringBootSecurity学习(21)前后端分离版之OAuth2.0非对称加密
  10. *.pvr.ccz文件还原成png格式