Wechat applet front and rear authorized login

1, Wechat applet front end

1.1 applet front end preparation

Due to the use of Web vant, it has not been installed or does not know how to install it. You can refer to it My blog.

upper Wechat public platform Register a small program. After registration, you will have APPID and SECRET.

1. api encapsulation

The wxapi folder is defined in the root directory. We encapsulate the api request independently and write request.js in the wxapi folder:

const requestObj = require('./request.config.js')

requestObj.request = ({
  url,
  method,
  data = '',
  token = ''
}) => {
  let _url = requestObj.API_BASE_URL + url
  return new Promise((resolve, reject) => {
    wx.showLoading({
      title: 'Loading...',
    })
    wx.request({
      url: _url,
      method: method,
      data,
      header: {
        // 'content-type': 'application/x-www-form-urlencoded',
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + token
      },
      success(request) {
        console.log(request)
        if (request.data.code == 401) {
          wx.navigateTo({
            url: '/pages/authpage/authpage',
          })
          wx.showToast({
            title: 'Please log in again',
            icon: 'none'
          })
        }
        resolve(request.data)
      },
      fail(error) {
        reject(error)
        wx.navigateTo({
          url: '../networkerror/networkerror',
        })
      },
      complete() {
        // Load complete
        wx.hideLoading()
      }
    })
  })
}
/**
 * promise extension finally method of applet
 */
Promise.prototype.finally = function (callback) {
  var Promise = this.constructor;
  return this.then(
    function (value) {
      Promise.resolve(callback()).then(
        function () {
          return value;
        }
      );
    },
    function (reason) {
      Promise.resolve(callback()).then(
        function () {
          throw reason;
        }
      );
    }
  );
}

module.exports = requestObj

We write the relevant configuration to request.config.js (the same level directory as request.js):

const requestObj = {
  API_BASE_URL: 'http://jtminiprogramapi.com/api ', / / applet interface online address
  // API_BASE_URL: 'http://192.168.91.112:8085/ ', / / offline address of applet interface
}

module.exports = requestObj

Then create an api folder in the wxapi folder, write the apis of our modules in it, and write userApi.js under the apis folder (we will write all the user related interfaces here, and only demonstrate user login):

const requestObj = require('../request')

let userApi = {
  /* Wechat login to get token */
  getToken: (data, method) => requestObj.request({
    url: '/wxlogin', method: method, data
  }),

}

module.exports = userApi;

Write index.js in wxapi folder:

const userApi = require('./apis/userApi');
module.exports = {
  userApi,
}

After the api module is encapsulated, its directory structure is as follows:

2. Authorization independent page

Write an independent authorization page in wechat developer tool:
authpage.wxml:

<view class='headView'>
  <open-data class='icon' mode="aspectFit" type="userAvatarUrl"></open-data>
  <view class='icon'></view>
</view>
<view class="auth-btn">
   <button bindtap="getUserProfile">Authorized login</button>
</view>
<view class="cancel-btn" bindtap="cancelAuth">Cancel authorized login</view>
<van-toast id="van-toast" />

authpage.js:

import Toast from '@vant/weapp/toast/index';
const WXAPI = require('../../wxapi/index');
Page({

  /**
   * Initial data of the page
   */
  data: {

  },
  // Click Cancel authorization
  cancelAuth () {
    wx.switchTab({
      url: '../index/index'
    })
  },
  getUserProfile () {
    wx.getUserProfile({
      desc: 'Improve personal data', // Declare the purpose of obtaining the user's personal information, which will be displayed in the pop-up window later. Please fill in carefully
      success: (newWes) => {
        let userInfo = newWes.userInfo
        wx.setStorageSync('userInfo', newWes.userInfo)

        wx.login({
          success (res) {
            let code = res.code
            if (code) {
              wx.showLoading({
                title: 'Loading',
              })
              WXAPI.userApi.getToken({
                userInfo,
                code
              }, 'POST').then((res) => {
                console.log(res)
                wx.setStorageSync('authFlag', true)
                wx.setStorageSync('token', res.access_token)
                wx.navigateBack({
                  delta: 1
                })
              }, (err) => {
                console.log(err)
              }).finally(() => {
                wx.hideLoading({})
              })
            }
          }
        })
      },
      fail: (err) => {
        console.log(err)
      }
    })
  },
  /**
   * Life cycle function -- listening for page loading
   */
  onLoad: function (options) {

  },

  /**
   * Life cycle function -- monitor the completion of the first rendering of the page
   */
  onReady: function () {

  },

  /**
   * Life cycle function -- monitor page display
   */
  onShow: function () {

  },

  /**
   * Life cycle function -- listening for page hiding
   */
  onHide: function () {

  },

  /**
   * Life cycle function -- listen for page unloading
   */
  onUnload: function () {

  },

  /**
   * Page related event handler -- listen to user drop-down actions
   */
  onPullDownRefresh: function () {

  },

  /**
   * Handler for bottom pull event on page
   */
  onReachBottom: function () {

  },

  /**
   * Users click the upper right corner to share
   */
  onShareAppMessage: function () {

  }
})

authpage.wxss:

.headView {
  display: flex;
  justify-content: center;
  align-items:center;
  margin-top: 50rpx;
  height:300rpx;
  width:750rpx;
  position:relative;
  margin-bottom: 50rpx;
  }
 
/**
*open-data Your head can't be rounded
*Here, a hollowed out view is covered. The boundary of the hollowed out view is made into the same color as the surrounding background, and a pseudo fillet is made
**/
.headView .icon {
    position: absolute;
    height: 200rpx;
    width: 200rpx;
    border-radius: 50%;
    border: 50rpx solid #f1f1f1;
}
.cancel-btn {
    display: block;
    margin-left: auto;
    margin-right: auto;
    padding-left: 14px;
    padding-right: 14px;
    box-sizing: border-box;
    font-size: 18px;
    text-align: center;
    text-decoration: none;
    line-height: 2.55555556;
    border-radius: 5px;
    -webkit-tap-highlight-color: transparent;
    overflow: hidden;
    cursor: pointer;
    color: #000;
    background-color: #f8f8f8;
    margin-top: 50rpx;
    padding: 8px 24px;
    line-height: 1.41176471;
    border-radius: 4px;
    font-weight: 700;
    font-size: 17px;
    width: 184px;
    margin-left: auto;
    margin-right: auto;
    position: relative;
}
.auth-btn {
  width: 184px;
  margin: 0 auto;
  height: 40px;
}
button {
  height: 100%;
  line-height: 40px;
  font-weight: normal;
  background-color: #546D7A;
  color: #fff;
}
button::after {
  border: none;
}
.cancel-btn {
  font-weight: normal;
}

authpage.json:

{
  "usingComponents": {
    "van-toast": "@vant/weapp/toast/index"
  },
  "navigationBarTitleText": "Authorized login"
}

2, Wechat applet backend (laravel)

2.1 applet backend preparation

1. Project installation, dingo/api and jwt certification

You can refer to my This article.

2. Create applet user tables and models

Run the command PHP artists make: model miniprogram / mpuser - M:

Migration file write field:

Schema::create('mp_users', function (Blueprint $table) {
            $table->id();
            $table->string('openid')->comment('User applet unique id');
            $table->string('nickname')->comment('User applet nickname');
            $table->string('avatar')->comment('User applet Avatar');
            $table->string('country')->comment('User applet country');
            $table->string('province')->comment('User applet');
            $table->string('city')->comment('User applet City');
            $table->string('weixin_session_key')->comment('User login session');
            $table->string('gender')->comment('User gender: 1 -> Male, 0 -> female');
            $table->string('name')->nullable()->comment('User's real name');
            $table->string('email')->nullable()->comment('User mailbox');
            $table->timestamps();
        });


Run the migration command php artisan migrate:

3. Install easywechat plug-in

This plug-in allows you to connect to the wechat interface faster.
Run the command composer require "Overtrue / laravel wechat: ^ 6.0":

Exclude wechat related routes in middleware App\Http\Middleware\VerifyCsrfToken:

Run the command php artisan vendor:publish --provider="Overtrue\LaravelWeChat\ServiceProvider" to publish related configurations.
Open the applet configuration in config/wechat.php:

Then write to the. env file:

4. Create applet authorization login authentication controller

Run the command php artisan make:controller Auth/mpAuthorizationsController:

Write method:

<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Models\miniProgram\mpUser;
use GrahamCampbell\ResultType\Result;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

class mpAuthorizationsController extends Controller
{
    /**
     * name: SWT User login, applet wechat login
     */
    public function store(Request $request)
    {
        Log::debug($request->all());
        $code = $request->code;
        $nick_name = $request->userInfo['nickName'];
        $avatar = $request->userInfo['avatarUrl'];
        $gender = $request->userInfo['gender'];
        $country = $request->userInfo['country'];
        $province = $request->userInfo['province'];
        $city = $request->userInfo['city'];

        // Get wechat openid and session according to code_ key
            $miniProgram = \EasyWeChat::miniProgram();
            $data = $miniProgram->auth->session($code);

        // If the result is incorrect, the code has expired or is incorrect, and a 401 error is returned
        if (isset($data['errcode'])) {
            return Result::fail('code incorrect');
        }

        // Find the user corresponding to openid
        $userInfo = mpUser::where('openid', $data['openid'])->first();

        $attributes['weixin_session_key'] = $data['session_key'];
        if(!$userInfo){
            //Update user information
            $userInfo = new mpUser();
            $userInfo->openid = $data['openid'];
            $userInfo->weixin_session_key = $data['session_key'];
            $userInfo->nickname = $nick_name;
            $userInfo->avatar = $avatar;
            $userInfo->gender = $gender;
            $userInfo->country = $country;
            $userInfo->province = $province;
            $userInfo->city = $city;

            $userInfo->save();
        }else{
            // Update user data
            $userInfo->update($attributes);
        }


        // Create a JWT for the corresponding user
        $token = auth('api')->login($userInfo);
        return $this->respondWithToken($token)->setStatusCode(201);

    }

     /**
     * Get the token array structure.
     *
     * @param  string $token
     *
     * @return \Illuminate\Http\JsonResponse
     */
    protected function respondWithToken($token)
    {
        return response()->json([
            'status_code' => '1',
            'msg' => 'Login succeeded!',
            'access_token' => $token,
            'token_type' => 'Bearer',
            'expires_in' => auth('api')->factory()->getTTL() * 60
        ]);
    }

}

5. Authorized login route

routes/api.php:

<?php

use App\Http\Controllers\Auth\mpAuthorizationsController;

$api = app('Dingo\Api\Routing\Router');

$api->version('v1', function ($api) {

    // Route to log in
    $api->group(['middleware' => 'api.auth'], function($api) {
        $api->get('users', [\App\Http\Controllers\TestController::class, 'users']);
    });

    // Execute login
    $api->any('wxlogin', [mpAuthorizationsController::class, 'store']);
});

3, Test effect



The applet has sent the request and got the token.
Next, let's check whether the database contains the user information of our login applet and the session that needs to deal with the wechat server_ key:

You can see that we basically have all the relevant user information here, including avatar nicknames openid and session_key.

On the way of learning actual combat, if you think this article is helpful to you, please pay attention to praise and comment on Sanlian. Thank you. Your support must be another support for my blog.

Tags: PHP Laravel Mini Program wechat

Posted on Mon, 04 Oct 2021 21:10:39 -0400 by Maknis