首页> 实战笔录 >PHP开发笔记 >ThinkPHP ThinkPHP
TP5.1实现微信小程序用户登录后端代码分享
作者:小萝卜 2019-11-22 【 TP5 】 浏览 1910
简介先来看官方提供的流程图:客户端:小程序客户端通过 wx.login() 获取登录code , 然后将code当做参数传递到服务器、
先来看官方提供的流程图:
客户端:
小程序客户端通过 wx.login() 获取登录code , 然后将code当做参数传递到服务器、
getToken(){
var that = this;
wx.login({
success: function (res) {
wx.request({
url: 'http://wx.shop.com/api/v1/token', //服务器获取token的api
method:'POST',
data: {
code : res.code
},
success: function (res) {
console.log(res)
}
})
}
})
}
服务器端(ThinkPHP5.1):
1. 根据客户端传递的 code , 请求微信提供 api 换取该用户的 openid 和 session_key ,同一个用户在同一个小程序中的 openid 是不变的
<?php
namespace appcommonservice;
use appcommonmodelUser;
/**
* UserToken类用作颁发微信令牌,继承与Token
*/
class UserToken extends Token {
protected $code;
protected $Appid;
protected $AppSecret;
protected $LoginUrl;
public function __construct($code) {
$this->code = $code;
//从服务器换取 openid 需要传递三个参数
// Appid、Appsecret、Code
$this->Appid = config('wx.app_id');
$this->AppSecret = config('wx.app_secret');
//sprintf的作用是将字符串中占位符用特定值按顺序替换
$this->LoginUrl = sprintf(config('wx.login_url'), $this->Appid, $this->AppSecret, $this->code);
}
/**
* 根据用户传递 code 去微信服务器换取 openid
*/
public function get() {
$result = curl_get($this->LoginUrl);
$wxResult = json_decode($result, true);
if (empty($wxResult)) {
throw new Exception("获取session_key和open_id失败,微信内部错误");
}
//验证获取令牌是否成功
if (array_key_exists('errcode', $wxResult)) {
throw new appcommonexceptionBaseException([
'errorCode' => $wxResult['errcode'],
'msg' => $wxResult['errmsg'],
]);
} else {
return $this->grantToken($wxResult['openid']);
}
}
/**
* 颁发令牌 并将用户信息序列化成json,已token为键保存在本地缓存
* 作用是 当用户不存在时创建用户 存在时返回用户 id
*/
private function grantToken($openid) {
//查找User表,查看该openid对应用户是否存在,如是则返回uid,否则生成新用户,返回uid
$user = User::where('openid', $openid)->find();
if (!$user) {
$uid = User::create([
'openid' => $openid,
]);
} else {
$uid = $user->id;
}
//存入缓存 key:生成返回客户端的令牌 value:openid + uid
$key = $this->generateToken();
$cache_value['openid'] = $openid;
$cache_value['uid'] = $uid;
$expire = config('token.expire');
if (!cache($key, $cache_value, $expire)) {
throw new Exception("缓存客户令牌时出现错误");
} else {
return $key;
}
}
}
使用前需要先定位配置文件
<?php
return [
// +---------------------------------
// 微信相关配置
// +---------------------------------
// 小程序app_id
'app_id' => 'wx0a1d95f443204af2',
// 小程序app_secret
'app_secret' => 'a29462308699ae469d5fb6cc54a9a95a',
// 微信使用code换取用户openid及session_key的url地址
'login_url' => "https://api.weixin.qq.com/sns/jscode2session?" .
"appid=%s&secret=%s&js_code=%s&grant_type=authorization_code",
// 微信获取access_token的url地址
'access_token_url' => "https://api.weixin.qq.com/cgi-bin/token?" .
"grant_type=client_credential&appid=%s&secret=%s",
//支付状态
'unpaid' => 1,
'paid' => 2,
'shipped' => 3,
];
基类Token
<?php
namespace appcommonservice;
use thinkFacadeRequest;
// 这里将token的相关操作放在service层
// 定义了一个Token基类,基类中存放生成 token、根据token从缓存中获取用户数据操作
class Token {
/**
* 生成随机字符串 作为 token
*/
public function generateToken() {
$randChar = getRandChar(32);
$timestamp = $_SERVER['REQUEST_TIME_FLOAT'];
return md5($randChar . $timestamp);
}
/**
* 根据用户携带的 token ,从缓存中读取用户信息
*/
public static function getCurrentIdentity() {
$token = Request::header('token');
if (!$token) {
throw new appcommonexceptionBaseException(['msg' => '请先登录']);
}
$identity = cache($token);
if ($identity) {
return $identity;
} else {
throw new appcommonexceptionBaseException(['msg' => '身份已过期,请重新登录']);
}
}
/**
* 获得保存在缓存指定键的值
*/
public static function getCurrentTokenVar($var) {
$indentity = self::getCurrentIdentity();
if (!$indentity[$var]) {
throw new Exception(['msg' => '尝试获取的Token变量并不存在']);
} else {
return $indentity[$var];
}
}
}
控制器中使用
class Token extends Controller {
public function getToken() {
$code = $this->request->param('code');
(new TokenValidate())->getToken($code);
$ut = new UserToken($code);
return json([
'token' => $ut->get(),
]);
}
}
微信支付等操作都依赖于 openid
很赞哦! (0)
相关文章
- tp5.0使用think-queue+redis实现消息队列简易教程
- TP6使用Jwt验证token时报错Cannot pass parameter 3 by reference
- tp5怎么获取一个数组参数
- TP6使用redis操作报错Store [redis] not found.
- TP框架右下角运行时间
- TP6 Validate内置验证规则总览
- TP6上传图片验证时报错think\\Validate::check() must be of the type array
- tp5 报错variable type error: array怎么解决
- ThinkPHP集成QueryList和PhantomJS插件实现采集动态加载的页面的数据
- tp5判断一张数据表是否存在