欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

解决微信H5静默授权获取code以及H5页面历史回退死循环问题

程序员文章站 2022-03-26 20:18:36
摘要 近期在开发H5页面相关需求,需求中有个微信静默授权登录的功能,之前没有接触过这个功能,经过调研官方文档,开发出了初级方案;初级方案可以解决获取code,但是页面返回上一个页面时,需要连续返回两次才可以回到上一个页面。经过获取流程分析,解决了返回循环的bug。 初级方案原理 当时调研完官方文档后 ......

摘要

   近期在开发h5页面相关需求,需求中有个微信静默授权登录的功能,之前没有接触过这个功能,经过调研官方文档,开发出了初级方案;初级方案可以解决获取code,但是页面返回上一个页面时,需要连续返回两次才可以回到上一个页面。经过获取流程分析,解决了返回循环的bug。

 

初级方案原理

  当时调研完官方文档后,发现授权流程是重定向的方式,就傻白甜的直接在需要微信code的页面直接获取code并跳转回当前页,这样就造成了页面获取死循环的bug。为了解决获取code死循环的bug,在获取code时,建立一个中间也获取微信的code,code获取后将code存储到sessionstorage里,最后再重定向回页面,具体流程如下图所示:

解决微信H5静默授权获取code以及H5页面历史回退死循环问题

 

 ·初级方案路由history

  从路由history可以看出,初级方案建立一个微信获取code的页面,于是在路由的history多了一层授权的路由,所以返回作品列表需要连续返回两次才会回到列表页。路由history堆栈表如下图所示:

解决微信H5静默授权获取code以及H5页面历史回退死循环问题

 

终极方案原理

  根据初级方案的授权模式进行改动,进入作品详情页判断urlcode和localcode是否都有值,值为空或者null,获取微信code。当urlcode有值时,执行history.goback(),这样既可以防止页面循环获取code刷新操作,又可以去除history中获取微信code的历史路由。具体流程示意图如下所示:

解决微信H5静默授权获取code以及H5页面历史回退死循环问题

 

 ·终极方案路由history

  终极方案是直接在当前的作品页获取code并跳转回作品页,免去了一层调用获取code页组件的路由。这样做会引起页面循环获取code,所以需要判断urlcode和localcode来决定是否继续循环获取,还是做history.goback()。具体的路由history堆栈表如下图所示:

解决微信H5静默授权获取code以及H5页面历史回退死循环问题

 

react实现方案

  理清了终极的微信静默授权登录实现方案,我们就可以根据思路来编写我们需要的功能代码了,个人在开发中是使用的react-hook,所以就微信授权这个功能,自定义了一个usewxcode的可用hook。具体代码如下:

import { useeffect } from 'react';
import { usehistory } from 'react-router-dom';

// 获取用于微信授权的 code,卸载后会自动清除
export const usewxcode = () => {
  const history = usehistory();
  useeffect(()=>{const searchparams = new urlsearchparams(window.location.search);
    const urlcode = searchparams.get('code');
    const localcode = sessionstorage.getitem('code');
    if (!urlcode && !localcode) {
      const appid = 'xxxxxxxx'; // 微信授权的公众号的appid
      const redirecturl = encodeuricomponent(window.location.href);
      window.location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${redirecturl}&response_type=code&scope=snsapi_base&state=123#wechat_redirect`;
    } else if (urlcode) {
      sessionstorage.setitem('code', urlcode);
      history.goback();
    }
    return ()=>sessionstorage.removeitem('code');
  },[]);
  
  return sessionstorage.getitem('code');
}

 

  组件中获取授权的code:

import react from 'react';
// 引入usewxcode.js
import { usewxcode } from '@/utils/usewxcode';

const test = () => {
  const code = usewxcode();

  return (
    <div>
      测试  
    </div>
  )    
}    

export default test;

 

 

参考: