晓夏

北漂的女孩

Good Luck To You!

微信小程序开发(一)授权登录

浏览量:385

login.png

一、微信小程序获取发起请求获取code,发送给服务器

微信小程序,已经给出来很专业的技术文档,我们就按照他们给的步骤一点一点来就ok,不会有问题

var env = require('../config/env.js');
const DATAURL = env.getDomain('dataUrl');
const IMGCDNURL = env.getDomain('imgCdnUrl');

function loginSmall(func) {
  var app = getApp()
  //调用登录接口
  var that = this;
  wx.login({
    success: function (login_res) {
      if (login_res.code) {
        wx.getUserInfo({
          success: function (res) {
            typeof cb == "function" && cb(that.globalData.userInfo)
            //请求登录
            wx.request({
              url: DATAURL+'/app.php?c=SmallLogin&m=smallLoginAuth',
              method: 'POST',
              header: {
                'content-type': 'application/x-www-form-urlencoded',
                'loginType': 'smallapp'
              },
              dataType: 'json',
              data: { encryptedData: res.encryptedData, 
              iv: res.iv, smallcode: login_res.code },
              success: function (resu) {
                console.log(resu);          
                if (resu.data.errno == 10000) {
                  wx.showToast({
                    title: '登录成功',
                    icon: 'success',
                    duration: 1000
                  })
                  //把sessionid存入storage
                  wx.setStorage({
                    key: 'sid',
                    data: resu.data.data.sid
                  })
                  if (typeof func == "function") func();
                  
                } else if (resu.data.errno == 10001) {
                  wx.showToast({
                    title: '登录失败',
                    icon: 'loading',
                    duration: 2000
                  })
                } else if (resu.data.errno == 10002) {
                  wx.showToast({
                    title: resu.data.msg,
                    icon: 'loading',
                    duration: 2000
                  })
                } else if (resu.data.errno == 10003) {
                  wx.showToast({
                    title: resu.data.msg,
                    icon: 'loading',
                    duration: 2000
                  })
                } else {
                  wx.showToast({
                    title: '登录失败,请稍后重试',
                    icon: 'loading',
                    duration: 2000
                  })
                }
              },
              fail: function () {
                wx.showToast({
                  title: '系统错误',
                  icon: 'loading',
                  duration: 2000
                })
              }
            })
          }
        })
      } else {
        console.log('获取用户登录态失败!' + login_res.errMsg)
      }
    },
    fail: function(){
      wx.showToast({
        title: '获取登录状态失败',
        icon: 'loading',
        duration: 2000
      })
    }
  });
}

module.exports = {
  loginSmall: loginSmall,
}

二微信服务器拿code凭证获取session_key和openid解密用户信息存入session返回给小程序

PHP登录接口获取的小程序的授权信息:

<?php
/**
 *  FileName:        SmallLogin.php
 *  Description:    微信小程序登录
 *  Author:        <lianghuiju@chuchujie.com>
 *  Date Time:        17/09/05
 */
defined('BASEPATH') OR exit('No direct script access allowed');
class SmallLogin extends CI_Controller
{
    const SAPP_ID = "";//官方id
    const SAPP_SECRET = "";//微信小程序都有给出直接换成自己的

    //HTTP请求默认配置
    public $curl_errno = 0;
    public $curl_error = '';

    //小程序登录
    public function smallLoginAuth() {

        $smallcode = $this->input->get_post('smallcode');
        $encryptedData =  $this->input->get_post('encryptedData');
        $iv =  $this->input->get_post('iv');
        
        $keyData = $this->requestUserInfo($smallcode);
        if (!empty($keyData)){
            include(APPPATH . '../vendor/smallApp/wxBizDataCrypt.php');
            $pc = new WXBizDataCrypt($this::SAPP_ID, $keyData['session_key']);
            //检验数据的真实性,并且获取解密后的明文.
            $errCode = $pc->decryptData($encryptedData, $iv, $data);
            if ($errCode == 0) {
                $user_info = json_decode($data,true);
                $user_id = $this->getOpenidUserId($user_info);
                if($user_id !== false){
                    $this->session->user_id = $user_id;
                    $this->session->xaphp_sopenid = $user_info['openId'];
                    $this->session->unionid = $user_info['unionId'];

                }else{
                    //获取user_id 失败 或 注册失败
                    $this->renderOutput(array(), 10001, '登录失败', true);
                }

            }else {
                log_message('NOTE', '拼团小程序-解密用户信息失败'.$errCode);
                $this->renderOutput(array(),10002,$errCode.'获取用户信息失败10002',true);
            }

        } else{
            //获取解密Key失败
            $this->renderOutput(array(),10003,'获取用户信息失败10003',true);

        }
        $session_id = $this->session->sid;
        //约定成功登录的状态码为10000
        $lastData = array(
            'sid' => $session_id
        );

        $this->renderOutput($lastData, 10000, '登录成功', true);
    }

    /**
     * 向微信服务器 使用登录凭证 code 获取 session_key 和 openid
     * @param $code
     * @return mixed
     * author        : xujiwu@jiayuan.com
     * function_name : decodeUserInfo
     * description   :
     */
    public function requestUserInfo($code) {
        //小程序唯一标识
        $wxspAppid = $this::SAPP_ID;
        //小程序的 app secret
        $wxspSecret = $this::SAPP_SECRET;
        //授权(必填)
        $grant_type = "authorization_code";
        //////向微信服务器 使用登录凭证 code 获取 session_key 和 openid
        $params = "appid=" . $wxspAppid . "&secret=" . $wxspSecret 
        . "&js_code=" . $code . "&grant_type=" . $grant_type;
        $url = "https://api.weixin.qq.com/sns/jscode2session?" . $params;
        //发送请求
        $sr = $this->httpGet($url);
        //解析相应内容(转换成json对象)
        $json = json_decode($sr, true);
        if (empty($json['errcode'])) {
            return $json;
        } else {
            //请求失败上报
            reportCount(2309);
            log_message('NOTE','小程序-'.$json['errcode'].":".$json['errmsg']);
            return array();
        }
    }

    /**
     * 获取用户uid 未注册则注册
     * @author yangshengkai@chuchujie.com
     * @lastModifyTime 2017/9/5
     * @lastModify yangshengkai@chuchujie.com
     * @param getOpenidUserId
     * @return bool
     */
    public function getOpenidUserId($sappUserInfo){
        $openid = $sappUserInfo['openId'];
        $phone_number = '';
        $this->load->model('UsersAccount');
        $this->load->model('Users');
        //第二个参数为是否获取password,默认false
        $user_info = $this->UsersAccount->getUserIdByUserName($openid, true);
        $user_id = $user_info['user_id'];
        if (empty($user_id)){
            $timestamp = time();
            //注册新小程序用户
            $username = 'sapp_' . crc32($openid) . '_' . mt_rand(1, 10000);
            $password = md5($username . mt_rand(1000, 9999));
            $uname = isset($sappUserInfo['nickName'])&&!empty($sappUserInfo['nickName']) 
            ? $sappUserInfo['nickName']: 'chuchu_'.mt_rand(1000,9999);
            $headimgurl = isset($sappUserInfo['avatarUrl'])
            &&!empty($sappUserInfo['avatarUrl']) ?$sappUserInfo['avatarUrl'] : '';
            $new_user = array(
                'user_name' => $username,
                'password' => $password,
                'reg_time' => $timestamp,
                'last_login' => $timestamp,
                'uname' => $uname,
                'headimgurl' => $headimgurl,
                'openid' => $openid,
                'phone_number' => $phone_number
            );

            $user_id = $this->Users->insert($new_user);

            //插入到账号表中
            if ($user_id) {
                $user_account['user_id'] = $user_id;
                $user_account['login_type'] = 3;//代表小程序登录
                $user_account['user_name'] = $openid;
                $user_account['password'] = $password;
                $user_account['reg_time'] = $timestamp;
                $user_account['last_login'] = $timestamp;

                $account_id = $this->UsersAccount->insertData($user_account);
            }
        }
        if (empty($user_id)) {
            return false;
        }
        return $user_id;
    }

    //发起GET请求
    public function httpGet($url, $data = null) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 2000);
        curl_setopt($ch, CURLOPT_TIMEOUT_MS, 5000);

        $tmpInfo = curl_exec($ch);
        $this->curl_errno = curl_errno($ch);
        if ($this->curl_errno) {
            $this->curl_error = curl_error($ch);
            $param_str = (is_array($data) || is_object($data)) 
            ? json_encode($data) : (is_null($data) ? 'NULL' : $data);
            $errmsg = "Curl Error {$this->curl_errno}:{$this->curl_error} 
            method[GET] url[$url] params[$param_str]";
            log_message('NOTE', $errmsg);
        }
        curl_close($ch);
        return $tmpInfo;
    }

}

官方给给出解密的文档和demo,你直接按照管饭给出来的来做就ok,下载地址

wxpintuan.rar

特别需要主要的是:

        微信小程序是么有cookie这个概念的,我们之前的网站是session是基于cookie存储的。

        所以在小程序请求服务器存储session是存入失败的,因此需要修改

图片.png











神回复

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。