token和session的区别:
token和session其实都是为了身份验证,session一般翻译为会话,而token更多的时候是翻译为令牌;session在服务器端会保存一份,可能保存到缓存、文件或数据库;session和token都是有过期时间一说,都需要去管理过期时间;token的思想是算法验证,session的思想是信息存储对比。 token是有多种方案的,可以设计成无需存储,token同时也是跨域的,session是要存储的,存储在数据库的思想;其实token与session的问题是一种时间与空间的博弈问题,session是空间换时间,而tbken是时
间换空间。虽然确实都是“客户端记录,每次访问携带”,但 token 很容易设计为自包含的,也就是说,后端不需要记录什么东西,每次一个无状态请求,每次解密验证,每次当场得出合法 /非法的结论。
以下是一个简单的生成token方法,也可以使用插件去生成,比如jwt扩展插件,这里为了简单就直接不用插件了。
一、首先创建用户表:包含token和token过期时间,登录时间
CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `phone` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `realname` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL, `password` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL, `status` tinyint(2) DEFAULT '0', `created_at` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL, `updated_at` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL, `login_time` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL, `token` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL, `time_out` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
二、使用PHP编写登录方法:这里使用的ThinkPHP6的写法,原生原理也是一样的。
<?php public function login(){ $phone = input('phone'); $password = input('password'); if(empty($phone) || empty($password)){ return json(['code'=>500,'msg'=>'error','data'=>'参数错误']); } $res = Db::name("user")->where(array('phone'=>$phone))->find(); if($res){ if($res['password'] == md5($password)){ $token = sha1( md5(uniqid(md5((string)microtime(true)),true))); //生成一个不会重复的token $time_out = time()+3600; //1小时过期事件 $data = [ "token"=>$token, "time_out"=>$time_out, "login_time"=>time() ]; $update = Db::name("user")->where(array('phone'=>$phone))->update($data); if($update){ $resToken = Db::name("user")->where(array('phone'=>$phone))->find(); if($resToken){ return json(['code'=>200,'msg'=>'success','data'=>$resToken['token']]); }else{ return json(['code'=>500,'msg'=>'error','data'=>'登录失败']); } }else{ return json(['code'=>500,'msg'=>'error','data'=>'登录失败']); } }else{ return json(['code'=>500,'msg'=>'error','data'=>"账号或密码错误"]); } }else{ return json(['code'=>500,'msg'=>'error','data'=>'账号不存在']); } } ?>
说明:这里生成一个不重复的token,以及一小时就过期的时间,用户每次登录的时候都刷新token,并更新到数据库
<?php $token = sha1( md5(uniqid(md5((string)microtime(true)),true))); //生成一个不会重复的token $time_out = time()+3600; //1小时过期事件 ?>
三、验证token是否过期:这里使用的ThinkPHP6的写法,原生原理也是一样的。
<?php public function checklogin(){ $token = input('token'); if($token){ $res = Db::name("user")->where(array('token'=>$token))->find(); if($res){ if(time() - $res['time_out'] > 0){ return json(['code'=>500,'msg'=>'error','data'=>'登录已过期,请重新登录']); }else{ return json(['code'=>200,'msg'=>'success','data'=>'登录验证成功']); } }else{ return json(['code'=>500,'msg'=>'error','data'=>'请先登录']); } }else{ return json(['code'=>500,'msg'=>'error','data'=>'参数错误']); } } ?>
说明:前端传递token给后端,后端根据用户传递过来的token去数据表里查询该用户的数据,判断当前时间戳减去登录保存的过期时间,再判断过期时间是大于0,大于0即为token已过去,用户需要重新登录。
文章评论(0)