php微信小程序授权登录,thinkphp 微信登录

  php微信小程序授权登录,thinkphp 微信登录

  源码也在我的开源代码库中给出

  https://github.com/wulongtao/think-wxminihelper

  下面结合框架框架来实现以下微信小程序的登录流程,这些流程是结合了官网和开源代码库的一个网站综合实现的

  https://mp.weixin.qq.com/debug/wxadoc/dev/api/api-login.html?t=2017112#wxloginobject

  https://github.com/cantoo/learning-wxapp/blob/master/微信小程序登录态验证流程。钔

  我已经把登录流程做了一下简单的封装,你也可以直接使用设计者下载直接使用:

  设计者需要xxh/think-wxminihelper

  登录流程图参考了如下两个图:

  按照上面的步骤,代码实现如下:

  /**

  * 登录

  函数wxLogin(func) {

  //调用登录接口

  //1.小程序调用wx。登录得到代码。

  wx.login({

  成功:函数(资源){

  var code=RES[ code ];

  //2.小程序调用wx.getUserInfo得到原始数据,签名,加密数据。

  wx.getUserInfo({

  成功:函数(信息){

  控制台。日志(信息);

  var raw data=info[ raw data ];

  var signature=info[ signature ];

  var encrypt data=info[ encrypt data ];

  var加密数据=info[加密数据];//注意是加密数据不是加密数据.坑啊

  var iv=info[ iv ];

  //3.小程序调用计算机网络服务器获取代币接口,传入代码、原始数据、签名、加密数据。

  wx.request({

  网址:常量。登录_网址,

  数据:{

  代码:代码,

  原始数据:原始数据,

  签名:签名,

   encryptData : encryptData,

  四:四,

  “加密数据”:加密数据

  成功:函数(资源){

  if(res.statusCode!=200) {

  wx.showModal({

  标题: 登录失败

  func== func func的类型(RES . data);

  $code=input(code ,, htmlspecialchars _ decode );

  $rawData=input(rawData ,, htmlspecialchars _ decode );

  $signature=input(signature ,, htmlspecialchars _ decode );

  $ encrypted data=input( encrypted data ,, htmlspecialchars _ decode );

  $iv=输入( iv ,, htmlspecialchars _ decode );

  * 4 .服务器调用微信提供的jsoncode2session接口获取openid,会话密钥,调用失败应给予客户端反馈

  * , 微信侧返回错误则可判断为恶意请求,可以不返回。微信文档链接

  * 这是一个超文本传送协议接口,开发者服务器使用登录凭证密码获取会话密钥和openid。其中会话密钥是对用户数据进行加密签名的密钥。

  * 为了自身应用安全,会话密钥不应该在网络上传输。

  * 接口地址: https://API。微信。QQ。 com/SNS/jscode 2会话? APPID=APPID SECRET=SECRET js _ code=JSCODE grant _ type=authorization _ code

  $params=[

  appid=$this- appid,

  secret=$this- secret,

  js_code=$code,

   grant_type=$this- grant_type

  $res=makeRequest($this- url,$ params);

  if ($res[code]!==200 !isset($res[result]) !isset($ RES[ result ]){

  返回JSON(ret _ message(请求令牌失败));

  $ req data=JSON _ decode($ RES[ result ],true);

  如果(!isset($ req data[ session _ key ]){

  返回JSON(ret _ message(请求令牌失败));

  $ session key=$ req data[ session _ key ];

  * 5 .服务器计算签名,并与小程序传入的签名比较,校验签名的合法性,不匹配则返回签名不匹配的错误。不匹配的场景可判断为恶意请求,可以不返回。

  * 通过调用接口(如wx.getUserInfo)获取敏感数据时,接口会同时返回原始数据、签名,其中签名=sha1(原始数据会话密钥)

  * 将签名、原始数据、以及用户登录态发送给开发者服务器,开发者在数据库中找到该用户对应的会话密钥

  * ,使用相同的算法计算出签名签名2,比对签名与签名2即可校验数据的可信度。

  $signature2=sha1($rawData .$会话密钥);

  if ($signature2!==$签名)返回ret _ message( signo match );

  * 6.使用第四步返回的会话密钥解密加密数据,将解得的信息与原始数据中信息进行比较,需要完全匹配,

  * 解得的信息中也包括openid,也需要与第四步返回的信息匹配。解密失败或不匹配应该返回客户相应错误。

  * (使用官方提供的方法即可)

  $ PC=new WXBizDataCrypt($ this-appid,$ session key);

  $ errCode=$ PC-解密数据($加密数据,$iv,$ data);

  if ($errCode!==0) {

  返回JSON(ret _ message( encryptDataNotMatch ));

  * 7.生成第三方第三届会议,用于第三方服务器和小程序之间做登录态校验。为了保证安全性,第三届会议应该满足:

  *答.长度足够长。建议有2^128种组合,即长度为16B

  * b .避免使用srand(当前时间)然后兰德()的方法,而是采用操作系统提供的真正随机数机制,比如Linux操作系统操作系统下面读取/dev/urandom设备

  * c .设置一定有效时间,对于过期的第三次会议视为不合法

  * 以$session3rd为密钥,会话密钥信息为值,写入服务器

  $data=json_decode($data,true);

  $ session 3 rd=randomFromDev(16);

  $ data[ session 3 rd ]=$ session 3 rd;

  缓存($session3rd,$data[openId].$会话密钥);

  函数ret_message($message=) {

  if ($message== )返回[result=0, message = ];

  $ ret=lang($ message);

  if (count($ret)!=2) {

  return [result=-1, message=未知错误];

  返回数组(

  result=$ret[0],

  message=$ret[1]

  * 发起超文本传送协议(超文本传输协议的缩写)请求

  * @param string $url访问路径

  * @param array $params参数,该数组多于一个,表示为邮政

  * @param int $expire请求超时时间

  * @param array $extend请求伪造包头参数

  * @ param stringhostIp主机的地址

  * @返回数组返回的为一个请求状态,一个内容

  函数makeRequest($url,$params=array(),$expire=0,$extend=array(),$hostIp= )

  if (empty($url)) {

  返回数组(“代码”=“100”);

  $ _ curl=curl _ init();

  $_header=array(

  接受-语言:中文-中文,

  连接:保持活动状态,

  "缓存控制:无缓存"

  //方便直接访问要设置宿主的地址

  如果(!空($hostIp)) {

  $ urlInfo=parse _ URL($ URL);

  if(empty($ urlInfo[ host ]){

  $urlInfo[host]=substr(DOMAIN,7,-1);

  $ url= http://{ $ hostIp } { $ url }

  }否则{

  $ URL=str _ replace($ urlInfo[ host ],$hostIp,$ URL);

  $ _ header[]= Host:{ $ urlInfo[ Host ]} ;

  //只要第二个参数传了值之后,就是邮政的

  如果(!empty($params)) {

  curl_setopt($_curl,CURLOPT_POSTFIELDS,http _ build _ query($ params));

  curl_setopt($_curl,CURLOPT_POST,true);

  if (substr($url,0,8)==https://) {

  curl_setopt($_curl,CURLOPT_SSL_VERIFYPEER,FALSE);

  curl_setopt($_curl,CURLOPT_SSL_VERIFYHOST,FALSE);

  curl_setopt($_curl,CURLOPT_URL,$ URL);

  curl_setopt($_curl,CURLOPT_RETURNTRANSFER,true);

  curl_setopt($_curl,CURLOPT_USERAGENT, API PHP CURL );

  curl_setopt($_curl,CURLOPT_HTTPHEADER,$ _ header);

  如果($expire 0){

  curl_setopt($_curl,CURLOPT_TIMEOUT,$ expire);//处理超时时间

  curl_setopt($_curl,CURLOPT_CONNECTTIMEOUT,$ expire);//建立连接超时时间

  //额外的配置

  如果(!empty($extend)) {

  curl_setopt_array($_curl,$ extend);

  $ result[ result ]=curl _ exec($ _ curl);

  $ result[ CODE ]=curl _ getinfo($ _ curl,CURLINFO _ HTTP _ CODE);

  $ result[ info ]=curl _ getinfo($ _ curl);

  if ($result[result]===false) {

  $ result[ result ]=curl _ error($ _ curl);

  $ result[ code ]=-curl _ errno($ _ curl);

  curl _ close($ _ curl);

  返回$结果

  * 读取/dev/urandom获取随机数

  * @param $len

  * @返回混合字符串

  函数randomFromDev($len) {

  $fp=@fopen(/dev/urandom , Rb );

  $ result=

  if ($fp!==假){

  $结果. f=@ fread($ FP,$ len);

  @ fclose($ FP);

  其他

  触发器_错误(无法打开/dev/urandom。);

  //从二进制转换为字符串

  $ result=base64 _ encode($ result);

  //不删除任何全球资源定位器(Uniform Resource Locator)字符

  $result=strtr($result,/,-_ );

  返回substr($result,0,$ len);

  }

php微信小程序授权登录,thinkphp 微信登录