1、初识Token–意义与作用
2、微信身份体系设计
生成
校验
3、实现Token身份权限体系①
route.php
Route::post('api/:version/token/user','api/:version.Token/getToken');post:获取令牌 传递的code有一定的安全需求,所以稍微隐藏,放到post的body里面传递
controllerToken.php
?phpnamespace appapicontrollerv1;use appapiserviceUserToken;use appapivalidateTokenGet;class Token{ public function getToken($code = ''){ (new TokenGet())-goCheck(); $ut = new UserToken(); $token = $ut-get($code); return $token; }}validateTokenGet.php
?phpnamespace appapivalidate;class TokenGet extends BaseValidate{ protected $rule = [ 'code' = 'require|isNotEmpty' ]; protected $message = [//传递错误信息 'code' = '没有code还想获取token,做梦' ];}isNotEmpty的作用:有参数名但是没有值,require会通过
validateBaseValidate.php
protected function isNotEmpty($value,$rule='', $data='',$filed=''){ if (empty($value)) { return false; } else { return true; } }modelUser.php在数据库中有一个User表
?phpnamespace appapimodel;class User extends BaseModel{}由于业务比较复杂,在model上边封装一个service层,把
serviceUserToken.php
?phpnamespace appapiservice;class UserToken{ public function get($code){ }}model、service总结
model除了处理业务逻辑之外,还有很重要的功能——调用数据库访问层,实现数据库增删改查,而service是建立在model之上的。
model模型命名必须和我们的数据库名相同。否则不知道对应哪张表。
所有复杂的 放到service层,简单的粒度比较小的放到model层。
4、实现Token身份权限体系②
如何通过小程序传来的code码,到微信小程序里面获取到openid
小程序通过wx.login()获取到的code,换取用户的登录状态信息,包括用户的唯一标志openid,以及本次登陆的会话密钥session_key。
微信小程序给一个接口地址,调用接口地址,获取openid。所需要传入的一系列参数appid(小程序id),secrect(小程序秘钥),js_code(code)。
分成了两大块:
小程序自己获取code码;
把code码发送到我们的服务器,再由我们的服务器调用微信给我们的接口,最终获取到openid和session_key。
extrawx.php
?phpreturn [ 'app_id' = '自己的小程序id', 'app_secret' = '自己的小程序秘钥', 'login_url' = "https://api.weixin.qq.com/sns/jscode2session?". "appid=%s&secret=%s&js_code=%s&grant_type=authorization_code"];把需要传参的地方用%s占位符
serviceUserToken.php
?phpnamespace appapiservice;use thinkException;class UserToken{ protected $code; protected $wxAppID; protected $wxAppSecrect; protected $wxLoginUrl; //在构造函数里面把这个wxLoginUrl配置完整 function __construct($code) { $this-$code = $code; $this-wxAppID = config('wx.app_id'); $this-wxAppSecrect = config('wx.app_secret'); //调用sprintf占位符填写完整 $this-wxLoginUrl = sprintf(config('wx.login_url'), $this-wxAppID,$this-wxAppSecrect,$this-code); } }因为发送http请求是一个经常用到的,所以放到公共文件里面
common.php
?php//发送http请求函数function curl_get($url,$httpCode = 0){ $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,$url); curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); //不做证书校验,部署在linux下请改为true curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false); curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,10); $file_contents = curl_exec($ch); $httpCode = curl_getinfo($ch,CURLINFO_HTTP_CODE); curl_close($ch); return $file_contents;}serviceUserToken.php
在这里直接调用
public function get(){ $result = curl_get($this-wxLoginUrl); $wxResult = json_decode($result,true);//把字符串变成数组:true:数组;false:对象 if (empty($wxResult)){//若为空,则微信调用失败 throw new Exception('获取session_key及openID时异常,微信内部错误'); //为什么使用框架的Exception而不是使用用户自定义的异常处理? /*自定义的会作为结果返回到客户端去,但是这个是属于服务器内部的异常,这个会把它记录为日志。*/ } else{//进一步的做判断 $LoginFail = array_key_exists('errcode',$wxResult); //如果接口调用失败,微信会返回你一个errorcode码 if ($LoginFail){//失败,处理异常 $this-processLoginError($wxResyult); } else{//获取成功,颁发令牌 $this-grantToken(); } } }5、实现Token身份权限体系③
serviceUserToken.php
private function processLoginError($wxResult){ throw new WeChatException([//做一个自定义参数设置 'msg' = $wxResult['errmsg'], 'errorCode' = $wxResult['errcode'] ]); }在这里写一个异常处理函数:
为了扩展方便一些,比如发送邮件,记录日志
exceptionWeChatExceeption
?phpnamespace applibexception;class WeChatException extends BaseException{ public $code = 400; public $msg = '微信服务器接口调用失败'; public $errorCode = 999;}在这里自定义一个异常
serviceUserToken.php
private function grantToken($wxRssukt){ //拿到oppenid //数据库里看一下,这个openid是不是已经存在 //如果存在,则不处理,如果不存在,那么新增一个user记录 //生成令牌,准备缓存数据,写入缓存 //把令牌返回到客户端去 $openid = $wxRssukt['openid']; }在微信小程序通过wx.login获取code码,在postman里面输入url,body-row-json里面输入{“code”:”“}
6、实现Token身份权限体系④
//数据库里看一下,这个openid是不是已经存在
//如果存在,则不处理,如果不存在,那么新增一个user记录
modelUseer.php
查询数据库
?phpnamespace appapimodel;class User extends BaseModel{ public function getByOpenId($openid){ $user = self::where('openid','=',$openid) -find(); return $user; }}serviceUsertoken.php
private function grantToken($wxRssukt){ $openid = $wxRssukt['openid']; //如果存在,则不处理,如果不存在,那么新增一个user记录 if ($user){ $uid = $user-id; } else{ $uid = $this-newUser($openid);//使用模型插入数据 } //生成令牌,准备缓存数据,写入缓存 //缓存key:令牌 //value:wxRelsut(sessionkey openid);uid,scope(决定用户身份) $cachedValue = $this-prepareCachedValue($wxRssukt,$uid); } private function prepareCachedValue($wxResult, $uid){//准备缓存value的数据 $cachedValue = $wxResult; $cachedValue['uid'] = $uid; $cachedValue['scope'] = 16; return $cachedValue; } private function saveToCache($cachedValue){ $key = generateToken(); } private function newUser($openid){//插入数据函数 $user = UserModel::create([ 'openid' = $openid ]); return $user-id; }














