thinkphp5-用户获取令牌(token验证)

  1. 定义路由
Route::post('api/:version/token/user', 'api/:version.Token/getToken');```
  1. 编写控制器Token.php
  • .首先是在小程序端要获取code码来调用我们服务器的token/user的接口来获取令牌。
  • 新建TokenGet验证类验证code参数。
  • 生成token的业务代码写到了service\UserToken类中。
<?php
namespace app\api\controller\v1;
use app\api\service\UserToken;
use app\api\validate\TokenGet;
class Token {
    /**
     * 用户获取令牌(登陆)
     * @url /token/user
     * @POST code
     */
    public function getToken($code = '') {
        (new TokenGet())->goCheck();
        $wx = new UserToken($code);
        $token = $wx->get();
        return [
            'token' => $token
        ];

    }
}
  1. service\UserToken.php
  • .1,首先小程序的机制是用户调用我们的接口把code码发送到我们的服务器,我们将code,appid,appsecret,发送到微信的服务器来请求该用户的唯一标识(openid和session_key)。
  • 我们拿到了微信服务器返回给我们的openid之后,首先去我们的数据库的user表里面查看一下属于该openid的用户是否存在,如果已经存在,那么就不需要处理。如果不存在,就需要新增一条user记录。并返回该用户的uid。
  • 新增了一条user记录之后,我们就要为该用户生成令牌(一串无意义的字符串)
  • 将令牌先存到缓存里面去,(存到缓存而不是数据库是因为用户的身份权限这个业务是需要设置有效时间的,不能让令牌永久有效,就应该存到缓存)。
  • 我们调用tp5的缓存机制,把生成的令牌作为key,把从微信服务器返回的结果和,uid以及作用域scope作为value存到缓存里面。
<?php
namespace app\api\service;
use app\lib\exception\TokenException;
use app\lib\exception\WeChatException;
use app\api\model\User as UserModel;

class UserToken extends Token {
    protected $code;
    protected $wxLoginUrl;
    protected $wxAppID;
    protected $wxAppSecret;

//1.第一步:构造函数拼凑出微信服务器的请求url参数
    function __construct($code) {
        $this->code = $code;
        $this->wxAppID = config('wx.app_id');
        $this->wxAppSecret = config('wx.app_secret');
        $this->wxLoginUrl = sprintf(
            config('wx.login_url'), $this->wxAppID, $this->wxAppSecret, $this->code);
    }


//2. 第二步 向微信的服务器发送请求,判断请求的结果。
    public function get() {
        $result = curl_get($this->wxLoginUrl);

        // 注意json_decode的第二个参数true
        // 这将使字符串被转化为数组而非对象

        $wxResult = json_decode($result, true);

        if (empty($wxResult)) {
            throw new Exception('获取session_key及openID时异常,微信内部错误');
        } else {
            $loginFail = array_key_exists('errcode', $wxResult);
            echo '$loginFail这里';
            if ($loginFail) {
                $this->processLoginError($wxResult);
            } else {
            //表示请求的结果没有问题,成功的拿到了openid和session_key
                return $this->grantToken($wxResult);
            }
        }
    }


    private function grantToken($wxResult) {
        //拿到opinid,到数据库看一下这个openid是不是已经存在
        //如果已经存在,就不处理,如果不存在那么新增一条user记录。并返回uid,因为uid要存起来放到缓存里面
        //生成令牌,准备缓存数据,写入缓存
        //把令牌返回到客户端去
        //key:令牌
        //value:wxResult,uid,scope
        $openid = $wxResult['openid'];

        $user = UserModel::getByOpenID($openid);

        if ($user) {
            $uid = $user->id;
        } else {
            $uid = $this->newUser($openid);
        }
        
        $cachedValue = $this->prepareCachedValue($wxResult, $uid);
        $token = $this->saveToCache($cachedValue);
        return $token;

    }

    //写入缓存
    private function saveToCache($cachedValue) {
        //生成key(令牌就是一串随机的字符串)
        $key = self::generateToken();
        //因为$cachedValue是数组,就要把它转化为json格式的字符串作为键的值
        $value = json_encode($cachedValue);
        //令牌的过期时间就是缓存的过期时间
        $expire_in = config('setting.token_expire_in');

        //使用tp5自带的缓存(默认文件的缓存机制)
        $request = cache($key, $value, $expire_in);
        if(!$request){
            throw new TokenException([
                'msg'=>'服务器缓存异常',
                'errorCode'=>10005
            ]);
        }
        return $key;
    }

    //准备缓存数据
    private function prepareCachedValue($wxResult, $uid) {
        $cachedValue = $wxResult;
        $cachedValue['uid'] = $uid;
        $cachedValue['scope'] = 16;
        return $cachedValue;
    }

    //新增一条user记录
    private function newUser($openid) {
        $user = UserModel::create([
            'openid' => $openid
        ]);
    }

    // 获取微信服务器返回结果失败
    private function processLoginError($wxResult) {
        throw new WeChatException(
            [
                'msg' => $wxResult['errmsg'],
                'errorCode' => $wxResult['errcode']
            ]);
    }
}
  1. service\Token
<?php
namespace app\api\service;
use app\lib\exception\TokenException;
class Token {
    //生成token字符串
    public static function generateToken() {
        //32个字符组成一组随机字符串
        //getRandChar是在common.php公共文件里面
        $randChars = getRandChar(32);
        //用三组字符串,进行md5加密
        $timestamp = $_SERVER['REQUEST_TIME_FLOAT'];
        //salt 盐
        $salt = config('secure.token_salt');
        return md5($randChars . $timestamp . $salt);
    }
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值