当前位置:   article > 正文

PHP —— 用 ThinkPHP5.0 实现微信小程序登陆_thinkphp + 微信小程序登录

thinkphp + 微信小程序登录

PHP —— 用 ThinkPHP5.0 实现微信小程序登陆

《工欲善其事,必先利其器》
大家好,之前学习了 原生 PHP 和框架,今天我们运用框架 TP5.0 来实现一下微信小程序的用户登陆以及获取用户的信息接口。

一、创建 Wxuser 模型

一般 MVC 框架的数据操作,都是在 Model 层里面的,所以这里我们需要实现微信登陆的模型,代码如下,分为几个小功能点:

  1. 使用前端发来的 code 去换取 openid;
  2. 利用 openid 生成 token;
  3. 将 openid 和 token 以及用户信息入库。
<?php
namespace app\api\model; // 命名空间,根据自己的项目路径来生成
use think\Model; // 引入tp框架的Model类
use app\common\exception\BaseException; // 引入基础错误捕捉类
use think\Db; // 引入 tp 框架的Db类
use think\Cache; // 引入 tp 框架的缓存类

class Wxuser extends Model {
	private $appId;
	private $appSecret;
	public $error;
	public $token;

	protected $resultSetType = "collection"; // 设置返回类型
	protected $autoWriteTimestamp = true; // 自动记录时间戳

	/**
	* Wxuser constructor
	* @param $appId
	* @param $appSecret
	*/
	public function __construct() {
		$appKey = Db::name("appkey")->find(); // 查找管理后台入库的小程序信息
		$this->appId = $appKey["appId"];
		$this->appSecret = $appKey["appSecret"];
	}

	/**
	* 获取用户信息
	* @param $token
	* @return null|static
	* @throws \think\exception\DbException
	*/
	public static function getUser($token) {
		$open_id = Cache::get($token)['openid'];
		$userInfo = DB::name("wxuser")->where("open_id",$open_id)->find();
		if ($userInfo) {
			$userInfo["create_time"] = date('Y-m-d',$userInfo["create_time"]);
			$userInfo["update_time"] = date('Y-m-d',$userInfo["update_time"]);
		}
		return $userInfo;
	}

	/**
	* 用户登陆
	*/
	public function login($post) {
		// 微信登陆 获取session_key
		$session = $this->wxlogin($post["code"]);
		// 自动注册用户
		$user_id = $this->register($session["openid"],$post["nickName"],$post["avatarUrl"],$post["gender"]);
		// 生成token
		$this->token = $this->token($session["openid"]);
		// 记录缓存 7天
		Cache::set($this->token, $session, 86400 * 7);
		return $user_id;
	}

	/**
	* 微信登陆
	* @param $code
	* @return array|mixed
	* @throws BaseException
	* @throws \think\exception\DbException
	*/
	private function wxlogin($code) {
		// 获取当前小程序信息
		if (empty($this->appId) || empty($this->appSecret)) {
			throw new BaseException(['msg' => '请到 [后台-小程序设置] 填写appid 和 appsecret']);
		}
		// 微信登录 (获取session_key)
        if (!$session = $this->sessionKey($code)) {
            throw new BaseException(['msg' => $this->error]);
        }
        return $session;
	}

	 /**
     * 获取session_key
     * @param $code
     * @return array|mixed
     */
    public function sessionKey($code) {
        /**
         * code 换取 session_key
         * ​这是一个 HTTPS 接口,开发者服务器使用登录凭证 code 获取 session_key 和 openid。
         * 其中 session_key 是对用户数据进行加密签名的密钥。为了自身应用安全,session_key 不应该在网络上传输。
         */
        $url = 'https://api.weixin.qq.com/sns/jscode2session';
        $result = json_decode(curl($url, [
            'appid' => $this->appId,
            'secret' => $this->appSecret,
            'grant_type' => 'authorization_code',
            'js_code' => $code
        ]), true);
        if (isset($result['errcode'])) {
            $this->error = $result['errmsg'];
            return false;
        }
        return $result;
    }
	
	/**
     * 生成用户认证的token
     * @param $openid
     * @return string
     */
    private function token($openid) {
        return md5($openid . 'token_salt');
    }

	 /**
     * 获取token
     * @return mixed
     */
    public function getToken() {
        return $this->token;
    }

	/**
     * 自动注册用户
     * @param $open_id
     * @param $userInfo
     * @return mixed
     * @throws BaseException
     * @throws \think\exception\DbException
     */
    private function register($open_id, $nickName,$avatarUrl,$gender) {
        $userInfo['open_id'] = $open_id;
        $userInfo['nickName'] = preg_replace('/[\xf0-\xf7].{3}/', '', $nickName);
        $userInfo['avatarUrl'] = $avatarUrl;
        $userInfo['gender'] = $gender+1;
        $data=Db::name('wxuser')->where('open_id',$open_id)->find();
        if(!$data){
        	$userInfo['create_time']=time();     
        	$userInfo['update_time']=time();   
            $user_id = Db::name('wxuser')->insertGetId($userInfo);
        	if (!$user_id) {
	        	return json_encode(['code'=>0,'msg' => '用户注册失败']);
	        }
	        return $user_id;
        }else{
        	$userInfo['update_time']=time();
        	Db::name('wxuser')->where('id',$data['id'])->update($userInfo);
        	return $data['id'];
        }
    }
}
?>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149

二、创建 login 控制器

实现登陆 Controller 主要就是接收前端发送来的数据,然后把数据进行提纯处理。只留下有需要的部分,再将数据传递给 Model。

<?php
namespace app\api\controller;
use app\common\exception\BaseException;
use think\Controller;
use app\api\model\Wxuser;
use think\Db;
use think\Request; // 引入 tp 请求体类

class User extends Controller {
	/**
     * 用户自动登录
     * @return array
     * @throws \app\common\exception\BaseException
     * @throws \think\Exception
     * @throws \think\exception\DbException
     */
    public function login() {
        $model = new Wxuser;
        $user_id = $model->login($this->request->post());
        $token = $model->getToken();  
        return json_encode(['code'=>200,'user_id' => $user_id,'token'=>$token]);
    }

	/**
     * 获取用户信息
     * @return array
     * @throws \app\common\exception\BaseException
     * @throws \think\Exception
     * @throws \think\exception\DbException
     */
     public function loginInfo() {
		 if (!$token = $this->request->param("token")) {
			throw new BaseException(['code' => 0, 'msg' => '缺少必要的参数:token']);
		 }
		 if (!$user = Wxuser::getUser($token)) {
			 throw new BaseException(['code' => 0, 'msg' => '没有找到用户信息']);
		 }
		 return json_encode(['code'=>200,'data'=>$user]);
	 }
}
?>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

三、前端小程序登陆部分

前端就比较简单了,分为三个小功能点:

  1. 调用 wx.login API 获取用户的 code;
  2. 调用 wx.getUserProfile API 获取用户的个人信息;
  3. 调用上面实现的 login 接口,把个人信息和 code 传递给后端。
const loginApi = 'api/user/login'; // 对应 tp 的控制器路径
onLoad: function () {
    wx.login({
      success: res => {
          this.data.code = res.code;
      }
    })
},

// 这里就没有做 微信获取用户API的 适配了,有需要的自己上网查一下,搜索 canIUse
getUserProfile: function() {
    wx.getUserProfile({
        desc: '用户完善个人资料',
        success: res => {
            http.request(loginApi,{
                nickName: res.userInfo.nickName,//用户昵称
                avatarUrl: res.userInfo.avatarUrl,//用户LOGO
                code: this.data.code,//code值
                gender: res.userInfo.gender//性别
            },res=>{
                wx.setStorageSync('token', res.token)
                wx.setStorageSync('user_id', res.user_id)
                wx.navigateBack({
                  delta: 1
                })
            })
        },
        fail: function() {
            //用户按了拒绝按钮
            wx.showModal({
                title: '警告',
                content: '您已拒绝授权,将无法正常读取数据,请授权之后再进入!!!',
                showCancel: false,
                confirmText: '确认',
                success: function (res) {
                	if (res.confirm) {
                    	wx.navigateBack({
                    		delta: 1
                    	})
                	}
                }
            })
        }
    })
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

获取用户信息
拒绝登陆
登陆成功

四、前端小程序获取用户数据

const userApi = '/api/user/info'; // 对应 tp 控制器路径
var token;

onLoad: function(options) {
    token = wx.getStorageSync('token');
    //获取用户数据
    this.getUserData();
},

getUserData() {
    http.getData(userApi, {
      token: token
    }, res => {
      if (res.code == 200) {
        that.setData({
            userLogo: res.data.avatarUrl,
            userName: res.data.nickName,
            time: res.data.update_time
          })
      }
    })
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

成功获取

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/天景科技苑/article/detail/746744
推荐阅读
相关标签
  

闽ICP备14008679号