token是在输入了用户名和密码之后获取的,利用这个token你可以拥有查看或者操作相应的资源的权限。
接下来直接上代码,里面有详细注释。
controller/token
<?php
/**
* Created by PhpStorm.
* User: wzs
* Date: 2018/3/14
* Time: 10:07
*/
namespace app\api\controller\v1;
use app\api\service\UserToken;
use app\api\validate\TokenGet;
class Token
{
public function getToken($code=''){
(new TokenGet())->goCheck();
$ut = new UserToken();
$token = $ut->get($code);
return [
'token' => $token
];
}
}
service/Token
<?php
/**
* Created by PhpStorm.
* User: wzs
* Date: 2018/3/15
* Time: 16:29
*/
namespace app\api\service;
use app\lib\exception\TokenException;
use think\Cache;
use think\Exception;
use think\Request;
class Token
{
//生成令牌
public static function generateToken(){
//32 个字符组成一组随机字符串
$randChars = getRanChar(32);
//用三组字符串进行md5加密
$timestamp = $_SERVER['REQUEST_TIME_FLOAT'];
// salt 盐
$salt = config('secure.token_salt');
return md5($randChars.$timestamp.$salt);
}
public static function getCurrentTokenVar($key){
$token = Request::instance()->header('token');
$vars = Cache::get($token);
if(!$vars){
throw new TokenException();
}
else{
if(!is_array($vars)){
$vars = json_decode($vars,true); // 字符串变数组
}
if(array_key_exists($key,$vars)){
return $vars[$key];
}
else{
throw new Exception('尝试获取的token变量并不存在');
}
}
}
//
public static function getCurrentUid(){
// token
$uid = self::getCurrentTokenVar('uid');
return $uid;
}
}
service/UserToken
<?php
/**
* Created by PhpStorm.
* User: wzs
* Date: 2018/3/14
* Time: 10:32
*/
namespace app\api\service;
use app\lib\exception\TokenException;
use app\lib\exception\WeChatException;
use think\Exception;
use app\api\model\User as UserModel;
class UserToken extends Token
{
protected $code;
protected $wxAppID;
protected $wxAppSecret;
protected $wxLoginUrl;
function __construct($code)
{
$this->code = $code;
$this->wxAppID = config('wx.app_id');
$this->wxAppSecret = config('wx.app_secret');
//sprintf函数 把url中的s% 替换成想要的数据
$this->wxLoginUrl = sprintf(config('wx.login_url'),$this->wxAppID,$this->wxAppSecret,$this->code);
}
public function get()
{
$result = curl_get($this->wxLoginUrl);
$wxResult = json_decode($result, true);//result 变成json字符串
if (empty($wxResult)) {
throw new Exception('获取session_key及openID时异常,微信内部错误');
} else {
$loginFail = array_key_exists('errcode', $wxResult);
if ($loginFail) {
$this->processLoginError($wxResult);
}
else {
return $this->grantToken($wxResult);
}
}
}
//封装一个成功接收code的方法
private function grantToken($wxResult){
//拿到openID
//数据库里看一下,openID是否存在
//如果存在则不处理,不存在新增一条记录
//生成令牌,准备缓存数据,写入缓存
//把令牌返回到客户端
// key 令牌
// value :wxResult,uid,scope
$openid = $wxResult['openid'];
$user = UserModel::getByOpenID($openid);
if($user){
$uid = $user->id;
}
else{
$uid = $this->newUser($openid);
}
$cachedValue = $this->preparCacheValue($wxResult,$uid);
$token = $this->saveToCache($cachedValue);
return $token;
}
// 写入缓存
private function saveToCache($cachedValue){
$key = self::generateToken();
$value = json_encode($cachedValue);//把数组转换成字符串
$expire_in = config('setting.token_expire_in');
$request = cache($key,$value,$expire_in);
if(!$request){
throw new TokenException([
'msg' => '服务器缓存异常',
'errorCode' => 10005
]);
}
return $key;
}
//准备value的一系列数据
private function preparCacheValue($wxResult,$uid){
$cachedValue = $wxResult;
$cachedValue['uid'] = $uid;
$cachedValue['scope'] = 16; //权限高低2,4,6,8,12,14,16
return $cachedValue;
}
//openID不存在 则新增一条记录
private function newUser($openid){
$user = UserModel::create([
'openid' => $openid
]);
return $user->id;
}
//封装一个抛出异常的方法
private function processLoginError($wxResult){
throw new WeChatException([
'msg' => $wxResult['errmsg'],
'errcode' => $wxResult['errcode']
]);
}
}
validate/BaseValidate
<?php
/**
* Created by PhpStorm.
* User: wzs
* Date: 2018/3/6
* Time: 16:46
*/
namespace app\api\validate;
use app\lib\exception\ParameterException;
use think\Exception;
use think\Request;
use think\Validate;
class BaseValidate extends Validate
{
public function goCheck(){
// 获取http传入的参数
// 对这些参数做校验
$request = Request::instance();
$params = $request->param();
$result = $this->batch()->check($params);
if(!$result){
$ex = new ParameterException([
'msg' => $this->error,
]);
throw $ex;
}
else{
return true;
}
}
protected function isPositiveInteger($value,$rule = '',$data = '',$field = ''){
if(is_numeric($value) && is_int($value+0) && ($value+0) > 0){
return true;
}
else{
return false;
// return $field."必须是正整数";
}
}
protected function isNotEmpty($value,$rule = '',$data = '',$field = ''){
if(empty($value)){
return false;
}
else{
return true;
}
}
}
validate/TokenGet
<?php
/**
* Created by PhpStorm.
* User: wzs
* Date: 2018/3/14
* Time: 10:09
*/
namespace app\api\validate;
class TokenGet extends BaseValidate
{
protected $rule = [
'code' => 'require|isNotEmpty'
];
protected $message = [
'code' => '没有code还想获取Token,做梦呢'
];
}