Token refresh的实现
实现原理:
在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...
Token refresh的实现的更多相关文章
- token & refresh token 机制总结
token & refresh token 机制总结 废话 我在项目上写了个配置页面,之前很简单直接登录,毕竟配置页面自己人用就没有做token机制,后来公司的安全审核不过,现在要加上toke ...
- Refresh Tokens: When to Use Them and How They Interact with JWTs
In this post we will explore the concept of refresh tokens as defined by OAuth2. We will learn why t ...
- 翻译一篇英文文章,主要是给自己看的——在ASP.NET Core Web Api中如何刷新token
原文地址 :https://www.blinkingcaret.com/2018/05/30/refresh-tokens-in-asp-net-core-web-api/ 先申明,本人英语太菜,每次 ...
- 傻傻分不清之 Cookie、Session、Token、JWT
傻傻分不清之 Cookie.Session.Token.JWT 什么是认证(Authentication) 通俗地讲就是验证当前用户的身份,证明“你是你自己”(比如:你每天上下班打卡,都需要通过指纹打 ...
- 还分不清 Cookie、Session、Token、JWT?一篇文章讲清楚
还分不清 Cookie.Session.Token.JWT?一篇文章讲清楚 转载来源 公众号:前端加加 作者:秋天不落叶 什么是认证(Authentication) 通俗地讲就是验证当前用户的身份,证 ...
- cookie,session,token傻傻分不清
什么是认证(Authentication) • 通俗地讲就是验证当前用户的身份,证明"你是你自己"(比如:你每天上下班打卡,都需要通过指纹打卡,当你的指纹和系统里录入的指纹相匹配时 ...
- Bearer Token & OAuth 2.0
Bearer Token & OAuth 2.0 access token & refresh token http://localhost:8080/#/login HTTP Aut ...
- 授权认证登录之 Cookie、Session、Token、JWT 详解
一.先了解几个基础概念 什么是认证(Authentication) 通俗地讲就是验证当前用户的身份. 互联网中的认证: 用户名密码登录 邮箱发送登录链接 手机号接收验证码 只要你能收到邮箱/验证码,就 ...
- Cookie、Session、Token、JWT
什么是认证(Authentication)------->就是验证当前用户的身份,证明"你是你自己" 互联网中的认证: 用户名密码登录 邮箱发送登录链接 手机号接收验证码 只 ...
随机推荐
- Angular 样式绑定
1. style.propertyName [style.Css属性名] = 'Css属性值变量'/"'css属性值'" // app.component.ts export cl ...
- java程序猿如何练习java版的易筋经?
故事背景 电视剧<天龙八部>中,阿朱易容后进入少林寺偷走了<易筋经>,她一直想把这本书送给乔峰.耿直的乔峰觉得此书来历不正,不肯接受.几番波折,这本书最后落到聚贤庄庄主游坦之手 ...
- Scala 学习笔记之函数(3)
class student{ def sayHello(name: => String){ println(s"Hello, $name, welcome $name") } ...
- Java BIO及实现
发现日常学习过的知识不久就会遗忘,在此只是整理并记录一下学习笔记,做个回忆,并方便以后查阅,若有错误,欢迎指正 网络模型:TCP/IP网络模型是从OSI七层模型中演化来的,osi模型分为物理层,数据链 ...
- 2016 10月15日java的动手动脑
(1) 编写一个方法,使用以上算法生成指定数目(比如1000个)的随机整数. 源程序: //随机数的产生 //zhanxinwu,October,15,2016 public class Recur ...
- 不依赖远程API启动SEER区块链命令行钱包和网页钱包的方法
不依赖远程API启动命令行钱包和网页钱包的方法 在SEER的见证人操作等需要使用命令行钱包的操作中,我们介绍了通过钱包连接远程API来和区块链交互的方法.类似这样: cli_wallet.exe -s ...
- Unreal Engine 4 系列教程 Part 5:制作简单游戏
.katex { display: block; text-align: center; white-space: nowrap; } .katex-display > .katex > ...
- RF页面断言
title should be(断言title与预期指定的title内容相等): should be equal (断言某个字符串与预期指定的字符串相等) should not be equal ( ...
- postman参数化
1.新建csv文件 2.csv文件中输入变量名和参数 3.postman中新增接口,并设置变量 4.选择进入 5.导入参数化csv格式文件,点击run 查看运行结果
- PHP7源码之array_unique函数分析
以下源码基于 PHP 7.3.8 array array_unique ( array $array [, int $sort_flags = SORT_STRING ] ) (PHP 4 >= ...