微信小程序+php 授权登陆,完整代码

微信小程序+php 授权登陆,完整代码先上图实现流程:1、授权登陆按钮和正文信息放到了同一个页面,未授权的时候显示登陆按钮,已授权的时候隐藏登陆按钮,显示正文信息,当然也可以授权和正文分开成两个页面,在授权页面的onload里判断是否

大家好,又见面了,我是你们的朋友全栈君。

先上图

<span role="heading" aria-level="2">微信小程序+php 授权登陆,完整代码  <span role="heading" aria-level="2">微信小程序+php 授权登陆,完整代码  <span role="heading" aria-level="2">微信小程序+php 授权登陆,完整代码  <span role="heading" aria-level="2">微信小程序+php 授权登陆,完整代码

 

实现流程:

1、授权登陆按钮和正文信息放到了同一个页面,未授权的时候显示登陆按钮,已授权的时候隐藏登陆按钮,显示正文信息,当然也可以授权和正文分开成两个页面,在授权页面的onload里判断是否已授权,若已授权就直接跳转正文的页面。这里只说授权按钮和正文在同一页面的情况。

2、在onload里先判断是否已授权,如果已授权,就隐藏授权登陆按钮,显示正文信息,如果没有授权,显示授权登陆按钮。

3、前端使用button的open-type=”getUserInfo”来操作,点击授权按钮之后,“e”中会携带userInfo,用户的基本信息(和使用wx.getUserInfo接口获取的数据一样,所以我是在”e”里面直接取的,没有调用wx.getUserInfo接口)

4、使用wx.login接口获取登陆凭证code,使用code去后解密换取openid,传输code的时候带上第3步获取的用户信息一块发送给后台解密(也可以不携带,携带的目的是为了验证签名,这样安全一些,不验证也可以)

5、后台解密使用的是“auth.code2Session”接口,解密用到的SDK下载地址“https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/signature.html”。

5、后台解密之后(后台语言用的是php),会返回openid等敏感信息,就还可以把这些信息存起来了。

6、获取授权成功之后,再隐藏授权登陆按钮,显示正文信息。

7、如果用户点击拒绝授权,提示引导用户再次授权。

注意,要考虑到授权失败的情况

 

以下是详细代码

wxml

<view wx:if="{{isHide}}">
    <view wx:if="{{canIUse}}" >
        <view class='header'>
            <image src='/images/icon/wx_login.png'></image>
        </view>
 
        <view class='content'>
            <view>申请获取以下权限</view>
            <text>获得你的公开信息(昵称,头像等)</text>
        </view>
 
        <button class='bottom' type='primary' open-type="getUserInfo" lang="zh_CN" bindgetuserinfo="bindGetUserInfo">
            授权登录
        </button>
    </view>
    <view wx:else>请升级微信版本</view>
</view>
 
<view wx:else>
    <view>我的首页内容</view>
</view>

wxss

.header {
    margin: 90rpx 0 90rpx 50rpx;
    border-bottom: 1px solid #ccc;
    text-align: center;
    width: 650rpx;
    height: 300rpx;
    line-height: 450rpx;
}
 
.header image {
    width: 200rpx;
    height: 200rpx;
}
 
.content {
    margin-left: 50rpx;
    margin-bottom: 90rpx;
}
 
.content text {
    display: block;
    color: #9d9d9d;
    margin-top: 40rpx;
}
 
.bottom {
    border-radius: 80rpx;
    margin: 70rpx 50rpx;
    font-size: 35rpx;
}

js

// pages/test1/test1.js
var app = getApp();
Page({

  /**
   * 页面的初始数据
   */
  data: {
    //判断小程序的API,回调,参数,组件等是否在当前版本可用。
    canIUse: wx.canIUse('button.open-type.getUserInfo'),
    isHide: false
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    var that = this;
    // 查看是否授权
    wx.getSetting({
      success: function (res) {
        if (!res.authSetting['scope.userInfo']) {
          // 还未授权,显示授权按钮
          that.setData({
            isHide: true
          });
        } else {
          // 已授权,隐藏授权按钮,显示正文
          that.setData({
            isHide: false
          });
        }
      }
    })
  },

  //授权登陆按钮
  bindGetUserInfo: function (e) {
    var that = this;
    console.log(e)
    if (e.detail.userInfo) {
      //用户授权登陆,并跳转首页
      // that.getOpenid()
      wx.login({
        success: function (res) {
          // 请求自己后台获取用户openid
          wx.request({
            url: app.domain + 'teacherapi/Wx_Decode/WxDecode',
            method: 'POST',
            header: { 'content-type': 'application/x-www-form-urlencoded' },
            data: {
              encryptedData: e.detail.encryptedData,
              signature: e.detail.signature,
              rawData: e.detail.rawData,
              iv: e.detail.iv,
              code: res.code
            },
            success: function (res_user) {
              if (res_user.data.status == 0) {
                var data = JSON.parse(res_user.data.msg)    //json转对象
                //授权成功返回的数据,根据自己需求操作
                console.log(data)

                //授权成功后,隐藏授权按钮,显示正文
                that.setData({
                  isHide: false
                });
              }
            }, fail: function () {
              that.showModal('获取授权信息失败')
            }
          })
        }
      })
    } else {
      //用户按了拒绝授权按钮,提示引导授权
      that.showModal('请授权后使用小程序')
    }
  },

  //未授权弹窗
  showModal: function (e) {
    wx.showModal({
      title: '提示',
      content: e,
      showCancel: false,
      confirmText: '返回授权',
      success: function (res) {
        if (res.confirm) {
          console.log('用户点击了“返回授权”')
        }
      }
    })
  },

})

php

<?php
namespace app\teacherapi\controller;
use think\Controller;
/**
* @date: 2018-12
* 微信操作类
*/

class WxDecode extends Controller
{
    public function httpGet($url) {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_TIMEOUT, 500);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_URL, $url);
        $res = curl_exec($curl);
        curl_close($curl);
        return $res;
    }

    /**
     * @author: zxf
     * @date: 2018-12-08
     * @description: 解密微信用户敏感数据
     * @return array
     */
    public function WxDecode()
    {
        // 接收参数
        $data = request() -> param();
        

        // 引入解密文件 在微信小程序开发文档下载
        vendor('wx.WXBizDataCrypt');
        vendor('wx.ErrorCode');

        $appid = config('TESTPPID');
        $appsecret = config('TESTSECREET');
        $grant_type = "authorization_code"; //授权(必填)

        $code = $data['code'];        //有效期5分钟 登录会话

        $encryptedData=$data['encryptedData'];
        $iv = $data['iv'];
        $signature = $data['signature'];
        $rawData = $data['rawData'];

        // 拼接url
        $url = "https://api.weixin.qq.com/sns/jscode2session?"."appid=".$appid."&secret=".$appsecret."&js_code=".$code."&grant_type=".$grant_type;
        $res = json_decode($this->httpGet($url),true);


        $sessionKey = $res['session_key']; //取出json里对应的值
        $signature2 =  sha1(htmlspecialchars_decode($rawData).$sessionKey);
        // 验证签名
        if ($signature2 !== $signature){
            return json("验签失败");
        } 

        // 获取解密后的数据
        $pc = new \WXBizDataCrypt($appid, $sessionKey);
        $errCode = $pc->decryptData($encryptedData, $iv, $data );

        if ($errCode == 0) {
            return return_succ($data);
        } else {
            return return_error($errCode);
        }
    }
        
}

 思路说明:

1.调用wx.logo接口获取code凭证

2.通过button的open-type=”getUserInfo”事件,获取用户加密信息(也可以使用wx.getUserInfo接口获取加密信息)

3.后台解密:拿 code 和 获取到的加密信息,到后台解密

4.获取sessionKey :通过 code 调用 jscode2session接口 换取 sessionKey 

5.解密:通过 sessionKey 和 接收的加密信息进行解密,获取用户信息 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/155633.html原文链接:https://javaforall.net

(0)
上一篇 2022年7月3日 下午4:16
下一篇 2022年7月3日 下午4:16


相关推荐

  • foremost windows_windows上安装foremost – kalibb

    foremost windows_windows上安装foremost – kalibb做CTF题需要这工具来提取文件里的隐藏文件,网上大部分是linux版本,之前好不容易找了一个exe文件结果还不能用。找了很长时间终于找到了:用这个原代码你自己就可以编译出exe,如果懒得编译的话里面的binary里就有编译好的,直接用这个就好可以把前两个文件复制到一个安全的文件夹,方便以后使用,不要误删就好。分离文件的步骤:1.将所要解密的文件放入foremost所在的目录;进入foremos…

    2025年6月2日
    6
  • 谱聚类(Spectral Clustering)算法介绍

    谱聚类(Spectral Clustering)算法介绍一 前言本来想写关于聚类系列算法的介绍 但是聚类系列的其它几个算法原理比较简单 网上有大量的教程可以查阅 这里主要是介绍一下谱聚类算法 做一个学习笔记 同时也希望对想要了解该算法的朋友有一个帮助 关于聚类的其他系列算法 这里推荐一个写的很不错的博客 谱聚类在最近几年变得受欢迎起来 主要原因就是它实现简单 聚类效果经常优于传统的聚类算法 如 K Means 算法 刚开始学习谱聚类的时候 给人

    2026年3月19日
    2
  • 为什么Qwen3系列模型中没有720亿参数规模的Qwen3-72B?Qwen3-72B还会发布吗?NO!

    为什么Qwen3系列模型中没有720亿参数规模的Qwen3-72B?Qwen3-72B还会发布吗?NO!

    2026年3月13日
    2
  • netty原理分析

    netty原理分析1 Netty 简介 Netty 是一个高性能 异步事件驱动的 NIO 框架 基于 JAVANIO 提供的 API 实现 它提供了对 TCP UDP 和文件传输的支持 作为一个异步 NIO 框架 Netty 的所有 IO 操作都是异步非阻塞的 通过 Future Listener 机制 用户可以方便的主动获取或者通过通知机制获得 IO 操作结果 作为当前最流行的 NIO 框架 Netty 在互联网领

    2026年3月19日
    4
  • 三门问题详解(附C语言实现)

    三门问题详解(附C语言实现)三门问题 违背直觉的概率现象 nbsp nbsp 三门问题 MontyHallpro 亦称为蒙提霍尔问题 蒙特霍问题或蒙提霍尔悖论 大致出自美国的电视游戏节目 Let sMakeaDeal 问题名字来自该节目的主持人蒙提 霍尔 MontyHall 参赛者会看见三扇关闭了的门 其中一扇的后面有一辆汽车 选中后面有车的那扇门可赢得该汽车 另外两扇门后面则各藏有一只山羊 当参赛者选定了一扇门 但未去开启它的时候 节目主持人开启剩下两扇门的其中一扇 露出其中一只山羊 主持人其后会问参赛者要

    2026年3月19日
    1
  • spring循环依赖为什么不是二级缓存_有效循环血量不依赖

    spring循环依赖为什么不是二级缓存_有效循环血量不依赖前置知识:所谓的三级缓存只是三个可以当作是全局变量的Map,Spring的源码中大量使用了这种先将数据放入容器中等使用结束再销毁的代码风格Spring的初始化过程大致有四步我们说的循环依赖就是第四步在给Bean属性注入的时候发生的一个问题循环依赖就是:假设有两个类A和B,A中需要注入B,B中需要注入A由于A注入B时B没有创建,B创建时A也无法创建导致的死循环问题我们都知道AOP是Spring的一个重要核心思想,其实现就是根据动态代理来实现的,也就是说我们的Bean其实很大概率都是要生成代理类,让

    2025年7月13日
    8

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号