(共566篇)
全部分类

uniapp微信授权+nginx重定向案例
[ Uniapp ] 

Uniapp在开发微信内H5页面微信授权功能时的案例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import qs from 'qs';
function authWechat(params, type=1) {
  // 跳转到静默授权页
  const redirect_uri = encodeURIComponent(process.env.WXAUTH_ORIGIN + '?' + qs.stringify(params));
  const auth_type = type===1 ? 'snsapi_baseinfo' : 'snsapi_userinfo'
  const url = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${process.env.APP_ID}&redirect_uri=${redirect_uri}&response_type=code&scope=${auth_type}&state=STATE#wechat_redirect`;

  location.href = url;
}
export default {
 data(){
     return {
         options:{},
        }
    },
 onLoad(options){
     this.options = options;
    },
    methods:{
     auth(){
         authWechat({
             origin: location.origin+location.pathname,
                ...this.options
            })
        }
    }
}
1
2
3
4
  location / {
    rewrite (.*) $arg_origin permanent;
    index index.html;
  }

案例解读

先说一下以上案例在实际项目中将要执行的流程,

假设

  1. 当前打开页面地址为a.com/pages/vip/vip?type=1&age=2,
  2. 微信公众号中绑定的合法授权域名为 auth.com

那么页面在微信浏览器中的跳转踪迹为:

  1. 访问 a.com/pages/vip/vip?type=1&age=2
  2. 点击某个按钮后会跳转到 open.weixin.com/...redirect_uri=auth.com&origin=a.com/pages/vip/vip&type=1&age=2
  3. 微信静默(主动)授权后, 会访问 auth.com&origin=a.com/pages/vip/vip&type=1&age=2 , 但是被nginx拦截重定向到 a.com/pages/vip/vip&type=1&age=2 页面了

也就是说, 在这个过程中, 浏览器只进行了2次自动跳转

这里牵扯到两个重要的问题

  1. 微信授权中redirect_uri传参问题
  2. 是否允许用户在auth.com域名下操作业务问题

是否允许用户在auth.com域名下操作业务

先说一下为什么我们要在nginx中对访问auth.com的页面重定向到最初的域名.

  1. 微信公众平台只允许绑定2个合法的授权域名, 也就是说 如果你有三个业务域名a.com, b.com, c.com, 如果他们在授权后都停留到auth.com下, 那auth.com的虚拟主机应该绑定到哪个业务下呢 ( 当然了, 通过pathname来区分项目是可以区分项目的 )

  2. 实际业务中, 最好是把认证业务与普通业务分开处理, 所以最好是只把auth.com当做一个中间平台, 只用来获取微信授权返回的code, 不要让用户在这个域名下处理实际业务.

  3. 所以, auth.com获取到微信授权返回的code后, 自动跳转到原先的业务域名下即可

为什么要在nginx中对auth.com做重定向

假设不在nginx中对auth.com做重定向, 我们的访问流程应该是这样的: 先看一下, 正常情况下的授权流程:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// 第一步: 访问a.com/vip
const url = encodeURIComponent('auth.com')
window.open("https://open.weixin.qq.com/connect/oauth2/authorize?appid=${process.env.APP_ID}&redirect_uri=${url}&response_type=code&scope=${auth_type}&state=STATE#wechat_redirect")


// 第二步: open.weixin.qq.com
// 会自动跳转到redurec_uri对应的页面 auth.com?code=123456


// 第三步: auth.com?code=123456
// 调用项目接口, 拿code换取用户信息

这是一个最简单的授权案例, 但是思考这么一个问题:

微信公众平台的合法授权域名只能绑定2个, 如果公司有三个业务域名a.com, b.com, c.com, 如果他们在授权后都停留到auth.com下, 那auth.com的虚拟主机应该绑定到哪个业务下呢

所以在实际业务中, 最好是把认证业务与普通业务分开处理, 所以最好是只把auth.com当做一个中间平台, 只用来获取微信授权返回的code, 不要让用户在这个域名下处理实际业务. 让auth.com获取到微信授权返回的code后, 自动跳转到原先的业务域名下即可

要实现这个功能, 我们在第一步中, 给redirect_uri添加了一个参数origin, 第三步中可以通过这个参数跳转到最初的项目

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// 第一步: 访问a.com/vip
const url = encodeURIComponent('auth.com?origin=a.com/vip')
window.open("https://open.weixin.qq.com/connect/oauth2/authorize?appid=${process.env.APP_ID}&redirect_uri=${url}&response_type=code&scope=${auth_type}&state=STATE#wechat_redirect")


// 第二步: open.weixin.qq.com
// 会自动跳转到redurec_uri对应的页面 auth.com?origin=a.com/vip&code=123456


// 第三步: auth.com?origin=a.com/vip&code=123456
window.open('a.com/vip&code=123456')

// 第四步 a.com/vip&code=123456
// 调用项目接口, 拿code换取用户信息

现在出现了一个新的问题: 在这个过程中,浏览器自动跳转了3次, 第三步在跳转的过程中, 依然要在浏览器中加载auth.com的资源,才能跳转, 能不能把这个步骤放到nginx当中,在nginx中直接重定向呢?

nginxauth.com虚拟主机下, 添加如下代码:

1
2
3
4
5

  location / {
    rewrite (.*) $arg_origin permanent;
    index index.html;
  }

再次访问a.com/vip页面 ,它已经成功的减少了一步自动跳转.

现在又出现了新的问题, 假设我的当前页面地址带有query参数呢?

1
2
3
4
5
6
7
// 第一步: 访问a.com/vip?age=20&name=zhangsan
const url = encodeURIComponent('auth.com?origin=a.com/vip?age=20&name=zhangsan')
window.open("https://open.weixin.qq.com/connect/oauth2/authorize?appid=${process.env.APP_ID}&redirect_uri=${url}&response_type=code&scope=${auth_type}&state=STATE#wechat_redirect")


// 第二步: open.weixin.qq.com
// 会自动跳转到redurec_uri对应的页面 auth.com?origin=a.com/vip?age=20&name=zhangsan

第二步中就出问题了, 做过微信授权的都知道nignx在解析auth.com?origin=a.com/vip?age=20&name=zhangsan时, 地址中连续出现了两个? , 此时的地址会被解析为:

1
2
3
4
{
 origin:'a.com/vip?age=20',
 name:'zhangsan'
}

这就导致nginx会把页面重定向到a.com/vip?age=20页面,