服务器环境: centos7   php7.0

准备工作:

  • 注册小程序,并获取 appid 、appsecret
  • 下载微信解密算法sdk : https://mp.weixin.qq.com/debug/wxadoc/dev/api/signature.html
  • https 的域名。需要在小程序后台服务器域名那配置

  

代码实现

一 、 thinkphp5

1  /extend/wxdev   把下载的加密算法放进去

坑1 : 微信下载的文件编码为: UTF-8-bootom  ,注意自己转换一下(不会的直接新建文件。把代码复制进去)

坑2 :wxBizDataCrypt.php文件中  构造函数, 微信官方使用的和类名一致, php 高版本不支持(亲测: PHP5.6支持, PHP7.0 不支持)。请改为: __construct

2  新建微信配置文件: /application/extra/wechat.php

<?php
// +----------------------------------------------------------------------
// | Desc: 微信配置文件
// +----------------------------------------------------------------------
// | Author: 依然范儿特西
// +---------------------------------------------------------------------- return [ //微信小程序ID
"wx_appid"=>"",
//微信小程序密钥
'wx_appsecret'=>"",
//微信接口域名
"wx_request_url"=>"https://api.weixin.qq.com/sns/jscode2session", ];

3   /application/common.php

    /**
* 发送HTTP请求方法
* @param string $url 请求URL
* @param array $params 请求参数
* @param string $method 请求方法GET/POST
* @return array $data 响应数据
*/
function http_send($url, $params, $method = 'GET', $header = array(), $multi = false){
$opts = array(
CURLOPT_TIMEOUT => 30,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_HTTPHEADER => $header
);
/* 根据请求类型设置特定参数 */
switch(strtoupper($method)){
case 'GET':
$opts[CURLOPT_URL] = $url . '?' . http_build_query($params);
break;
case 'POST':
//判断是否传输文件
$params = $multi ? $params : http_build_query($params);
$opts[CURLOPT_URL] = $url;
$opts[CURLOPT_POST] = 1;
$opts[CURLOPT_POSTFIELDS] = $params;
break;
default:
throw new Exception('不支持的请求方式!');
}
/* 初始化并执行curl请求 */
$ch = curl_init();
curl_setopt_array($ch, $opts);
$data = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
if($error) throw new Exception('请求发生错误:' . $error);
return $data;
}

4 控制器代码:  /application/wechat/controller/Wx.php

<?php
namespace app\wechat\controller;
use think\Controller; //使用控制器
use think\Db; //使用数据库操作
use think\Request;
use think\config;
use Wxdev\WXBizDataCrypt;
/*
* 微信模块
*/
class Wxrun extends Base{
function __construct(){
parent::__construct();
} public function index(){
// 指定json数据输出
return json(['code'=>110,'message'=>"Power By 研发中心","result"=>null]);
} //用户登陆
public function user_login(){
$APPID = config::get("wechat.wx_appid");
$AppSecret = config::get("wechat.wx_appsecret");
$wx_request_url = config::get("wechat.wx_request_url");
$code = input("code");
$param = array(
'appid' => $APPID,
'secret' => $AppSecret,
'js_code' => $code,
'grant_type' => 'authorization_code'
);
// 一个使用curl实现的get方法请求
$arr = http_send($wx_request_url, $param, 'post');
$arr = json_decode($arr,true);
if(isset($arr['errcode']) && !empty($arr['errcode'])){
return json(['code'=>'2','message'=>$arr['errmsg'],"result"=>null]);
}
$openid = $arr['openid'];
$session_key = $arr['session_key']; // 数据签名校验
$signature = input("signature");
$signature2 = sha1($_GET['rawData'].$session_key); //别用框架自带的input,会过滤掉必要的数据
if ($signature != $signature2) {
$msg = "shibai 1";
return json(['code'=>'2','message'=>'获取失败',"result"=>$msg]);
} //开发者如需要获取敏感数据,需要对接口返回的加密数据( encryptedData )进行对称解密
$encryptedData = $_GET['encryptedData'];
$iv = $_GET['iv'];
include_once (EXTEND_PATH. 'Wxdev/wxBizDataCrypt.php');
$pc = new \WXBizDataCrypt($APPID, $session_key);
$errCode = $pc->decryptData($encryptedData, $iv, $data); //其中$data包含用户的所有数据
if ($errCode != 0) {
return json(['code'=>'2','message'=>'获取失败',"result"=>null]);
}
/****** */
//写自己的逻辑: 操作数据库等操作
/****** */
//生成第三方3rd_session
$session3rd = null;
$strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
$max = strlen($strPol)-1;
for($i=0;$i<16;$i++){
$session3rd .=$strPol[rand(0,$max)];
}
return json(['code'=>'1','message'=>'获取成功',"result"=>$session3rd]); } }

二 、 小程序代码:

直接在 app.js 编写

// 登录
wx.login({
success: res => {
// 发送 res.code 到后台换取 openId, sessionKey, unionId
var code = res.code;
wx.getUserInfo({
success: res => {
// 可以将 res 发送给后台解码出 unionId
this.globalData.userInfo = res.userInfo
var rawData = res.rawData;
var signature = res.signature;
var encryptedData = res.encryptedData;
var iv = res.iv;
wx.request({
url: 'https://www.test.com/wechat/wx/user_login',
data: {
"code": code,
"rawData": rawData,
"signature": signature,
'iv': iv,
'encryptedData': encryptedData
},
success: function (info) {
console.log(info);
}
})
// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
// 所以此处加入 callback 以防止这种情况
if (this.userInfoReadyCallback) {
this.userInfoReadyCallback(res)
}
}
})
}
})

三: 测试结果:

【小程序+thinkphp5】 用户登陆,返回第三方session3rd的更多相关文章

  1. Python小程序之用户登陆接口

    编写登陆接口 输入用户名密码 认证成功后显示欢迎信息 输错三次后锁定 程序逻辑图: 代码: #!/usr/bin/env python #_*_ coding:UTF-8 _*_ #__author_ ...

  2. 微信小程序之微信登陆 —— 微信小程序教程系列(20)

    简介: 微信登陆,在新建一个微信小程序Hello World项目的时候,就可以看到项目中出现了我们的微信头像,其实这个Hello World项目,就有一个简化版的微信登陆.只不过是,还没有写入到咱们自 ...

  3. 微信小程序 人脸识别登陆模块

    微信小程序---人脸识别登陆的实现 关键词:微信小程序 人脸识别 百度云接口 前言 这是一篇关于一个原创微信小程序开发过程的原创文章.涉及到的核心技术是微信小程序开发方法和百度云人脸识别接口.小程序的 ...

  4. 微信小程序中用户登录和登录态维护

    提供用户登录以及维护用户的登录状态,是一个拥有用户系统的软件应用普遍需要做的事情.像微信这样的一个社交平台,如果做一个小程序应用,我们可能很少会去做一个完全脱离和舍弃连接用户信息的纯工具软件. 让用户 ...

  5. 微信小程序新版用户授权方式处理

    最新更新(2018-12-27): 最近做了改版,做成默认进来就是首页,然后去判断有没有用户信息,没有的话再去判断用没授权过,如果授权过直接自动去获取,没有的话再跳转到授权页面.因为用户授权主要就是针 ...

  6. TODO:小程序的用户身份

    TODO:小程序的用户身份 小程序的用户身份有三种,一个管理员,二十个开发者,四十个体验者 1.管理员,可设置风险操作保护.风险操作提醒等操作. a)修改管理员,需要用到原管理员,新管理员的身份证号码 ...

  7. [微信小程序] 微信小程序获取用户定位信息并加载对应城市信息,wx.getLocation,腾讯地图小程序api,微信小程序经纬度逆解析地理信息

    因为需要在小程序加个定位并加载对应城市信息 然而小程序自带api目前只能获取经纬度不能逆解析,虽然自己解析方式,但是同时也要调用地图,难道用户每次进小程序还要强行打开地图选择地址才定位吗?多麻烦也不利 ...

  8. 基于微信小程序的用户列表点赞功能

    代码地址如下:http://www.demodashi.com/demo/13997.html 一.前言 (1).适合人群 1.微信小程序开发者 2.前端工程师 3.想入门学习小程序开发的人员 4.想 ...

  9. 图片的URL上传至阿里云OSS操作(微信小程序二维码返回的二进制上传到OSS)

    当我们从网络中获取一个URL的图片我们要存储到本地或者是私有的云时,我们可以这样操作  把url中的图片文件下载到本地(或者上传到私有云中)  public String uploadUrlToOss ...

  10. 微信小程序 获取用户信息并保存登录状态

    微信小程序 获取用户信息并保存登录状态:http://www.360doc.com/content/18/0124/11/9200790_724662071.shtml

随机推荐

  1. win32 数据类型 vs c#

    在C#中做很多应用需要使用win32 API,但发现原型函数的一些数据类型看起来非常费劲,甚至在C#中“没有”这种数据类型,查阅了一下资料,数据类型对应关系整理如下,希望对大家有用: BOOL=Sys ...

  2. MySQL ERROR 1045 (28000): Access denied for user 'root'@'localhost'解决

    MySQL ERROR 1045 (28000): Access denied for user 'root'@'localhost'解决: # /etc/init.d/mysql stop # my ...

  3. Error while adding new interface: failed to open /dev/vboxnetctl: No such file or directory

    Try this : sudo modprobe vboxnetadp ref: https://github.com/gasolin/foxbox/issues/32

  4. 聊一聊PV和并发、以及计算web服务器的数量的方法

    聊一聊PV和并发.以及计算web服务器的数量的方法 http://www.chinaz.com/web/2016/0817/567752.shtml 最近和几个朋友,聊到并发和服务器的压力问题.很多朋 ...

  5. 安卓开发笔记——GridView组件

    1.什么是GridView? GridView(网格视图)是按照行列的方式来显示内容的,一般用于显示图片,图片等内容,比如实现九宫格图,用GridView是首选,也是最简单的. 2.正文 GridVi ...

  6. Android开发学习笔记-自定义控件的属性

    若想让自定义控件变得更加方便灵活,则就需要对控件进行定义属性,使其用起来更方便. 下面是自定义控件属性的方法 1.添加attrs.xml,内容格式样式可以参考sdk\platforms\android ...

  7. [转] Linux常用命令大全(非常全!!!)

    出处:https://www.cnblogs.com/yjd_hycf_space/p/7730690.html Linux常用命令大全(非常全!!!) 最近都在和Linux打交道,感觉还不错.我觉得 ...

  8. Linux/Centos下/lib64/libc.so.6: version `GLIBC_2.14' not found问题

    Centos的某个版本下编译了一个可执行程序,复制到另外一个Centos环境下去执行,结果出现了以下错误: /lib64/libc.so.6: version `GLIBC_2.14' not fou ...

  9. Python下字符画(ascii art)生成

    之前在b站上看到有人用C写了个脚本把妹抖龙op转换成字符画的形式输出了,感觉比较好玩在下就用python也写了一遍(主要是因为python比较简单好用).这里就这里就不介绍字符画了,因为能搜到这个的肯 ...

  10. python Thread对象的setDaemon(True)的作用。

    1.如果主线程是永远都不会结束的,那设置一个线程为守护线程是没必要的,设不设置都一样. 2.什么时候需要设置为守护线程?如果希望子线程一直运行,可以把子线程的代码写在while True里面一直循环, ...