flutter web实现微信网页授权登录

1、首先我使用了Getx来管理路由和获得用户同意登录后的code

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);


  @override
  Widget build(BuildContext context){
    HttpUtil.getInstance();

    return GetMaterialApp(
      initialRoute: RouteConfig.home,
      getPages: RouteConfig.getPages,
    );
  }
}

class RouteConfig {
  ///主页面
  static const String home = "/";

  static const String login = "/login";
  static const String one = "/one";
  static const String two = "/two";
  static const String three = "/three";


  ///别名映射页面
  static final List getPages = [
    GetPage(name: home, page: () => HomePage()),
    GetPage(name: login, page: () => LoginPage()),
    GetPage(name: one, page: () => OnePage()),
    GetPage(name: two, page: () => TwoPage()),
    GetPage(name: three, page: () => ThreePage()),
  ];
}

2、根据token判断是否登录,没登陆就申请微信授权

void isLogin() async {
    var token = await SPUtil.getToken();
    if (token == "") {
      var appId = UrlKeys.APP_ID;
      //这个是授权同意后的回调地址,自己可以建一个空白页面,将链接放上去,在空白页面中获得code
      var redirectUrl = urlEncode(text: UrlKeys.REDIRECT_URL);
      String requestUrl =
          "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" +
              appId +
              "&redirect_uri=" +
              redirectUrl +
              "&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect";
      
      if (await canLaunch(requestUrl) != null) {
        await launch(requestUrl);
      } else {
        throw "Could not open link (" + requestUrl + ").";
      }
    }
  }

3、在空白页面中获得code,得到后请求后端接口

	if(Get.parameters.isNotEmpty){
      state.code = Get.parameters['code'];
      state.stateCopy = Get.parameters['state'];
      logic.getUserInfo();
    }
    
void getUserInfo(){
    HttpUtil.get(UrlKeys.WEB_INFO, {
      "code":state.code,
      "state":state.stateCopy
    }, (data){
      state.data=data;
      SPUtil.setToken(data["data"]["accessToken"]);
      SPUtil.setValue(SPUtil.OPEN_ID,data["data"]["openId"]);
      update();
    }, (error){

    });
  }

4、接口,用code换access_token和openid

	@CrossOrigin    //支持跨域
    @RequestMapping(value = "/web/info", method = {RequestMethod.GET})
    public Result webInfo(HttpServletRequest request) {
        String appId = "你公众号的appId";
        String secret = "你公众号的secret";
        String code = request.getParameter("code");
   
        // 拼接请求地址
        String requestUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appId + "&secret=" + secret + "&code=" + code + "&grant_type=authorization_code";
        // 获取网页授权凭证
        String data = HttpUtil.sendGet(requestUrl);
        JSONObject jsonObject = JSON.parseObject(data);
        if (null != jsonObject) {
            try {
                WeChatOauth2Token wat = new WeChatOauth2Token();
                wat.setAccessToken(jsonObject.getString("access_token"));
                wat.setExpiresIn(jsonObject.getIntValue("expires_in"));
                wat.setRefreshToken(jsonObject.getString("refresh_token"));
                wat.setOpenId(jsonObject.getString("openid"));
                wat.setScope(jsonObject.getString("scope"));
                return Result.success(wat);
            } catch (Exception e) {
                int errorCode = jsonObject.getIntValue("errcode");
                String errorMsg = jsonObject.getString("errmsg");
                System.out.println("第三方:【微信】获取网页授权凭证失败 :errcode:{" + errorCode + "} errmsg:{" + errorMsg + "}");
                return Result.fail(errorCode, errorMsg);
            }
        }
        return Result.fail(444, "获得token错误");
    }

5、用access_token和openid拉取用户信息

get请求:https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN

返回参数
{   
  "openid": "OPENID",
  "nickname": NICKNAME,
  "sex": 1,
  "province":"PROVINCE",
  "city":"CITY",
  "country":"COUNTRY",
  "headimgurl":"https://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",
  "privilege":[ "PRIVILEGE1" "PRIVILEGE2"     ],
  "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
}

其他的信息可以去微信开放文档里看
https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html

我遇到的问题

flutter-web会自动添在链接上添加#,路由导航也必须加着#,这就导致了微信授权回调时,会自动把#放在最后,回调不到正确的页面,也就没有办法得到code

来个例子

https://mho.xjz.world/#/login  //回调地址
正常情况下:https://mho.xjz.world/#/login?code=1&state=2
微信回调后却是:https://mho.xjz.world/?code=1&state=2#/login

本想着在路由中直接去掉#,但flutter这方面的文章很少,以至于想试试vue与nginx去掉#的办法,无果(太菜),只能曲线救国了

最后用宝塔路径重定向了一下,让回调地址变成了

https://mho.xjz.world/login
//下面这个是nginx重定向配置
rewrite ^/login(.*) https://mho.xjz.world/#/login permanent;

在这里希望有知道如何直接去掉#的大佬,提点一下,不胜感激

你可能感兴趣的:(flutter,前端,flutter,微信)