今天接到要修改Token的有效期限,之前没有接触过Token,于是找了很多资料,发现很多都不全,而且难以看懂,于是我现在打算写这篇记录一下,希望可以帮助到大家!!!
一,Token的工作原理
为了更好的方便大家记忆和理解,这里就提一下和Token原理非常相似的一个东西,那就是我们非常熟悉的session
Session
1客户端第一次发送请求到服务端,服务端会根据请求创建一个session,(该session就是以键值对的形式来存储会话信息)
2接着服务端会返回一个sessionID到客户端,一个sessionId对应一个session
3客户端接收到sessionId之后,会将该sessionId保存在客户端cookie中
4接着客户端下次再发送请求的时候,就会带上该sessionId
5服务端接收到对应的sessionId之后,会对该sessionId进行校验,是否存在对应的sessionId,若存在则,直接使用,若不存在,则重新为该请求创建一个session
上面说完了sessionId的实现原理,接下来就来说说Token的实现原理:
1客户端第一次发送登陆请求到服务端
2服务端接收请求之后,会对用户名和密码进行校验
3若检验成功,则该服务端会根据该用户信息生成对应的Token,并返回给客户端
4客户端接收到Token之后,会将其保存在cookie或本地缓存中
5客户端再次发送请求的时候,就会和sessionId一样带上这个Token,
6服务端接收到该Token之后,会对该Token进行校验,若验证成功,则该服务端就会执行对应的请求,同时Token会有过期时间设置,若超有效期,那么该Token会重新生成另外一个。
二,Token的实现流程:
1用户在客户端登录用户名和密码时,上传对应的参数到服务端
public Message GenerateToken(string username, string password, string client, string ip, string expiration, string callback)
{
2服务端对用户名的信息进行校验,若校验通过,则会生成对应的token
GenerateTokenResult result = TokenManager.LoginVerification(username, password, client, ip, expiration, callback);
if (result.success)
{
result = TokenManager.GetToken(username, expiration, result.token, result.expires);
}
2服务端对用户名的信息进行校验,若校验通过,则会生成对应的token
LoginVerification(username, password, client, referer, ip, expiration, callback, skipMenuTest);
校验过程原理比较简单,但是代码繁多,这里就主要把核心主题说一下:
1, 对传入的用户信息进行校验
2, 根据用户名到数据库中查询到对应的Token
(这里需要注意,第一次登陆的时候是没有token的)
2.2生成Token TokenManager.GetToken(username, expiration, result.token,result.expires);
生成Token最主要的就是通过UpdateToken方法,更新Token
public static GenerateTokenResult GetToken(string username,string expiration,string token, string tokenexpiration)
{
GenerateTokenResult result = new GenerateTokenResult() { token = token, expires = tokenexpiration};
//当前有效期为空的时候,生成新的token有效时间
double newExpiration = DateTime.Now.AddDays(30).ToMilliseconds1970();
if (!string.IsNullOrEmpty(expiration))
newExpiration = DateTime.Now.AddHours(double.Parse(expiration)).ToMilliseconds1970();
if (ConnectionStringManager.WorkflowDbType == DataBaseType.SQLSERVER)
{
try
{
result.token = UpdateToken(username, token ,tokenexpiration, newExpiration.ToString());
result.expires = newExpiration.ToString();
}
UpdateToken方法,实现两个功能:
1,判断该token是否为空,若为空,则生成token,(对应第一次登陆时,将token设置为)
2,通过执行SQL语句对该数据库进行更新
public static string UpdateToken(string loginName, string token,string tokenexpiration, string newExpiration)
{
if (ConnectionStringManager.WorkflowDbType == DataBaseType.SQLSERVER)
{
try
{
using (SqlConnection conn = new SqlConnection(ConnectionStringManager.WorkflowConnectionString))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
//if (string.IsNullOrEmpty(token) || string.IsNullOrEmpty(tokenexpiration) || double.Parse(tokenexpiration) < DateTime.Now.ToMilliseconds1970())
//第一次登陆的时候,token为零,需要生成Token
if (string.IsNullOrEmpty(token)|| string.IsNullOrEmpty(tokenexpiration))
{
token = Guid.NewGuid().ToString("N");
}
cmd.CommandText = "update XXX set token = '" + token + "', tokenexpiration = " + newExpiration + " where 工号 = '" + loginName + "'";
cmd.ExecuteNonQuery();
}
}
}