ThinkPHP实现微信小程序微信授权登录

网上找了很多教程都不好使,最后自己又研究了一番,终于成功了

一、总体设计

小程序登录流程:客户端通过调用wx.login(),获取登录凭证(code),将此code发往服务器,服务器通过调用 auth.code2Session 接口,使用 code 换取 openid、unionid、session_key 等ThinkPHP实现微信小程序微信授权登录

本实例中将openid作为用户唯一标识,存入数据库中。服务器后端通过ThinkPHP框架实现两个接口:

http://localhost/srclib/index.php/Home/User/wxlogin // 登录接口 http://localhost/srclib/index.php/Home/User/wxsign // 首次登录(微信授权登录)接口 

1. 登录状态的维持

小程序在初始化时,在小程序onLaunch生命周期函数中调用wx.login(),向登录接口发送请求,将code发送给服务器。服务器接收到code后,调用https://api.weixin.qq.com/sns/jscode2session接口,将code,appid和appSecret发送给微信官方服务器,服务器会收到用户唯一标识openid和会话密钥 session_key等信息

此时服务器后台在数据库User表中查询openid:

  • 如果在User表中没有查到该记录,则说明此用户是新用户,还未授权微信登录,服务器返回客户端的状态码err_code值为1,表示不存在该用户,需要用户手动授权微信登录;

  • 如果在User表中查到了该记录,则表示用户已授权微信登录,此时服务器返回客户端的状态码err_code值为0,表示登录成功,服务器将用户信息和状态码发送至前端。

客户端在接收到状态码后判断:

  • 若状态码为0,则表示登录成功。客户端接收到用户信息后,通过调用wx.setStorage官方提供了wx.getUserProfile接口,使用获取用户信息。在页面中加入一个button,监听用户点击,点击后获取用户信息,本实例中主要获取了用户昵称nickName和用户头像地址avatarUrl。之后向(微信授权登录)首次登录接口发送请求,输入数据为code、nickName和avatarUrl。

    服务端接收到这些参数后,首先调用https://api.weixin.qq.com/sns/jscode2session接口,将code,appid和appSecret发送给微信官方服务器,服务器会收到用户唯一标识openid等参数,然后在数据库User表中查询该openid:

    • 如果在User表中没有查到该记录,则将openid、nickName和avatarUrl构建为一条用户记录数据,插入User表中,服务器返回客户端的状态码err_code值为0,表示新用户授权登录成功,服务器将用户信息和状态码发送至前端;

    • 如果在User表中查到了该记录,则表示该用户重复授权,抛出异常,此时服务器返回客户端的状态码err_code值为1。

    二、步骤说明

    1. 用户首次进入,显示授权登录按钮

    ThinkPHP实现微信小程序微信授权登录

    2. 点击授权登录按钮,出现提示弹窗

    ThinkPHP实现微信小程序微信授权登录

    3. 点击允许后,登录成功,跳转至个人中心页

    ThinkPHP实现微信小程序微信授权登录

    4. 此后用户再次进入小程序,已自动登录,实现了登录状态的维持

    ThinkPHP实现微信小程序微信授权登录

    三、完整代码

    1. 小程序前端

    app.js

    // app.js App({   globalData: {     loginState: false, // 用户登录状态     userInfo: null // 用户信息   },   onLaunch() {     this.login() // 登录   },   _initial() { // Page初始化函数,用于读取本地缓存,并更新全局变量     this.globalData.userInfo = wx.getStorageSync('userInfo')     this.globalData.loginState = wx.getStorageSync('loginState')     console.log("登录状态:"+this.globalData.loginState)     console.log("用户信息:")     console.log(this.globalData.userInfo)   },   login() {     let _this = this     // 登录请求     wx.login({       success: res => {         wx.request({           url: 'http://localhost/srclib/index.php/Home/User/wxlogin',           method: 'post',           data: {             code: res.code           },           header: {             "Content-Type": "application/x-www-form-urlencoded"           },           success: function (res) {             if(res.data.error_code == 1) { // 用户未授权登录               console.log("error")               wx.setStorageSync('loginState', false)               wx.navigateTo({ // 跳转至授权页,等待用户授权                 url: '../auth/auth',                })             } else if(res.data.error_code == 0) { // 登录成功               wx.setStorageSync('userInfo', res.data.data) // 更新本地缓存               wx.setStorageSync('loginState', true)             }           }         })       }     })   } }) 

    profile.js

    // pages/profile/profile.js const app = getApp() const globalData = getApp().globalData Page({   data: {     userInfo: null   },   onLoad() {     app._initial() // 页面初始化     this.setData({       userInfo: globalData.userInfo     })   } }) 

    auth.js

    // auth.js const app = getApp() const globalData = getApp().globalData Page({   data: {     userInfo: null   },   onLoad() {     app._initial() // 页面初始化   },   getUserProfile(e) {     // 使用wx.getUserProfile获取用户信息     wx.getUserProfile({       desc: '展示用户信息', // 声明获取用户个人信息后的用途,后续会展示在弹窗中       success: (res) => {         globalData.userInfo = res.userInfo         this.setData({           userInfo: globalData.userInfo         })         this.sign()       }     })   },   sign() {     let _this = this     wx.showLoading({       title: '加载中',     })     // 用户首次登录请求     wx.login({       success: res => {         wx.request({           url: 'http://localhost/srclib/index.php/Home/User/wxsign',           method: 'post',           data: {             code: res.code,             name: globalData.userInfo.nickName,             avatarUrl: globalData.userInfo.avatarUrl           },           header: {             "Content-Type": "application/x-www-form-urlencoded"           },           success: function (res) {             if(res.data.error_code == 1) { // 用户登录失败               console.log("error")             } else if(res.data.error_code == 0) { // 用户登录成功               wx.setStorageSync('userInfo', res.data.data) // 更新本地缓存               wx.setStorageSync('loginState', true)               wx.hideLoading()               wx.showToast({                 title: '授权成功',                 icon: 'success',                 duration: 2000,                 complete: (res) => {                   wx.navigateTo({ // 跳转至个人中心页                     url: '../profile/profile',                   })                 },               })             }           }         })       }     })   } }) 

    profile.wxml

    <!--pages/profile/profile.wxml--> <view class="container">   <view class="userinfo">     <image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.face_url}}" mode="cover"></image>     <text class="userinfo-nickname">{{userInfo.username}}</text>   </view> </view> 

    auth.wxml

    <!--auth.wxml--> <view class="container">   <button type="primary" bindtap="getUserProfile">授权微信登录</button> </view> 

    2. 服务器后端

    <?php namespace HomeController; use ThinkController; class UserController extends BaseController {     /**      * 微信登录      * @return [type] [description]      */     public function wxlogin()     {         // 校验参数是否存在         if (!$_POST['code']) {             $return_data = array();             $return_data['error_code'] = 2;             $return_data['msg'] = '参数不足: code';             $this->ajaxReturn($return_data);         } else {             $appid = "wxc6a376950e1c45c0"; // appid             $secret = "632hjdcba4c2b972c591738hdga91fvg"; // app密钥             $code = $_POST['code']; // 小程序传来的code值             $curl = curl_init();             $url = "https://api.weixin.qq.com/sns/jscode2session?appid=" . $appid . "&secret=" . $secret . "&js_code=" . $code . "&grant_type=authorization_code";             curl_setopt($curl, CURLOPT_URL, $url);             curl_setopt($curl, CURLOPT_HEADER, 0);             curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);             $result = curl_exec($curl);             $json = json_decode($result); // 对json数据解码             $arr = get_object_vars($json);             $openid = $arr['openid'];             curl_close($curl);             // 检验是否已经授权登录             $User = M('User');             // 构造查询条件             $where = array();             $where['openid'] = $openid;             $user = $User->where($where)->find();             if ($user) {                 $return_data = array();                 $return_data['error_code'] = 0;                 $return_data['msg'] = '登录成功';                 $return_data['data']['userid'] = $user['userid'];                 $return_data['data']['username'] = $user['username'];                 $return_data['data']['face_url'] = $user['face_url'];                 $this->ajaxReturn($return_data);             } else {                 $return_data = array();                 $return_data['error_code'] = 1;                 $return_data['msg'] = '不存在该用户,请授权登录';                 $this->ajaxReturn($return_data);             }         }     }      /**      *首次授权登录      * @return [type] [description]      */     public function wxsign()     {         // 校验参数是否存在         if (!$_POST['code']) {             $return_data = array();             $return_data['error_code'] = 2;             $return_data['msg'] = '参数不足: code';             $this->ajaxReturn($return_data);         } else if (!$_POST['name']) {             $return_data = array();             $return_data['error_code'] = 2;             $return_data['msg'] = '参数不足: name';             $this->ajaxReturn($return_data);         } else if (!$_POST['avatarUrl']) {             $return_data = array();             $return_data['error_code'] = 2;             $return_data['msg'] = '参数不足: avatarUrl';             $this->ajaxReturn($return_data);         } else {             $appid = "wxc6a376950e1c45c0"; // appid             $secret = "632hjdcba4c2b972c591738hdga91fvg"; // app密钥             $code = $_POST['code']; // 小程序传来的code值             $curl = curl_init();             $url = "https://api.weixin.qq.com/sns/jscode2session?appid=" . $appid . "&secret=" . $secret . "&js_code=" . $code . "&grant_type=authorization_code";             curl_setopt($curl, CURLOPT_URL, $url);             curl_setopt($curl, CURLOPT_HEADER, 0);             curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);             $result = curl_exec($curl);             $json = json_decode($result); // 对json数据解码             $arr = get_object_vars($json);             $openid = $arr['openid'];             curl_close($curl);             // 检验是否已经授权过             $User = M('User');             // 构造查询条件             $where = array();             $where['openid'] = $openid;             $user = $User->where($where)->find();             if ($user) {                 $return_data = array();                 $return_data['error_code'] = 1;                 $return_data['msg'] = '登录失败';                 $this->ajaxReturn($return_data);             } else {                 // 构建插入的数据                  $data = array();                 $data['openid'] = $openid;                 $data['username'] = $_POST['name'];                 $data['face_url'] = $_POST['avatarUrl'];                 // 插入数据                 $result = $User->add($data);                 // add数据添加成功之后,返回的就是该条数据的id                 if ($result) {                     // 插入数据执行成功                     $return_data = array();                     $return_data['error_code'] = 0;                     $return_data['msg'] = '登录成功';                     $return_data['data']['userid'] = $result;                     $return_data['data']['username'] = $_POST['name'];                     $return_data['data']['face_url'] = $_POST['avatarUrl'];                     $this->ajaxReturn($return_data);                 } else {                     // 插入数据执行失败                     $return_data = array();                     $return_data['error_code'] = 1;                     $return_data['msg'] = '登录失败';                     $this->ajaxReturn($return_data);                 }             }         }     } } 

版权声明:玥玥 发表于 2021-04-07 22:59:28。
转载请注明:ThinkPHP实现微信小程序微信授权登录 | 女黑客导航