微信扫码登录只能填一个授权回调域问题

背景

公司增加了个微信扫码登录,费劲千辛万苦终于把应用申请下来了,但遇到了一个头疼的事情:微信授权回调域只能写一个,且不支持通配。这下可好了,总不能把每个需要微信登录的二级域名都申请一个应用吧?而且一个开放平台账号最多申请十个。

使用html重定向

这种方法网上一大堆,大体思想是,微信授权回调域写一个域名,然后将一个html页面放到这个域名下,微信扫码登录时填写的redirect_url就是到这个html,然后在这个html的js代码中,根据某一个参数去判断当前路由应该重定向到哪个地址。

html重定向做法

假如我们有多个地址需要做微信扫码登录,比如我们的研发环境,测试环境,生产环境都需要做微信扫码登陆,但又不想给研发测试环境做外网的端口映射,那么可以使用这种方式。
首先在开放平台的授权回调域中写一个公共授权域名,比如oauth.loooswc.cn
在这里插入图片描述
然后将get-wechat-code.html页面放到该域名下,比如oauth.loooswc.cn/oauth/wechat/get-wechat-code.html
最后在调用微信获取code请求时,redirect_url就写oauth.loooswc.cn/oauth/wechat/get-wechat-code.html?env={env}&request=/oauth/wechat/login_callback.do,通过js代码根据参数env去判断应该重定向到哪个地址,比如env=dev时,则重定向到http://localhost:4200/oauth/wechat/login_callback.do
但是这种办法有种缺点,就是会将研发测试环境的地址暴漏出去,而且这个地址对生产环境是没有任何意义的,虽然别人拿到这个内网地址也访问不通,但总归是不好的,所以我们可以使用下面这种方法,通过后台请求重定向。
附带get-wechat-code.html代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>微信登陆</title>
</head>
<body>
<script>
    function getUrlParams(key) {
        var args = {};
        var pairs = location.search.substring(1).split('&');
        for (var i = 0; i < pairs.length; i++) {
            var pos = pairs[i].indexOf('=');
            if (pos === -1) {
                continue;
            }
            args[pairs[i].substring(0, pos)] = decodeURIComponent(pairs[i].substring(pos + 1));
        }
        return args[key];
    }
    function getRealRedirectUrl(env){
        var realRedirectUrl = 'https://admin.loooswc.cn/';
        if('dev' == env){
            realRedirectUrl = 'http://localhost:8080/';
        }else if('test' == env){
            realRedirectUrl = 'http://192.168.1.10:30080/';
        }else if('pre-prod' == env){
            realRedirectUrl = 'http://192.168.1.20:30080/';
        }

        return realRedirectUrl;
    }
    function appendParams(params, url) {
        var baseWithSearch = url.split('#')[0];
        var hash = url.split('#')[1];
        for (var i = 0; i < params.length; i++) {
            if (params[i].value !== undefined) {
                var newParam = params[i].key + "=" + params[i].value;
                if (baseWithSearch.indexOf('?') > 0) {
                    var oldParamReg = new RegExp(params[i].key + '=[-\\w]{0,40}', 'g');
                    if (oldParamReg.test(baseWithSearch)) {
                        baseWithSearch = baseWithSearch.replace(oldParamReg, newParam);
                    } else {
                        baseWithSearch += "&" + newParam;
                    }
                } else {
                    baseWithSearch += "?" + newParam;
                }
            }
        }
        if (hash) {
            url = baseWithSearch + '#' + hash;
        } else {
            url = baseWithSearch;
        }
        return url;
    }
    var code = getUrlParams('code');
    var appId = getUrlParams('appid');
    var scope = getUrlParams('scope') || 'snsapi_base';
    var state = getUrlParams('state');
    var env = getUrlParams('env');
    var request = getUrlParams('request');
    var redirectUrl;
    if (!code) {
        redirectUrl = appendParams([{
            key: 'appid',
            value: appId
    }, {
            key: 'redirect_uri',
            value: encodeURIComponent(location.href)
        }, {
            key: 'response_type',
            value: 'code'
        }, {
            key: 'scope',
            value: scope
        }, {
            key: 'state',
            value: state
        }], 'https://open.weixin.qq.com/connect/oauth2/authorize#wechat_redirect');
            } else {
        redirectUrl = appendParams([{key: 'code', value: code},{
            key: 'state',
            value: state
        }], getRealRedirectUrl(env) + request);
    }
   location.href = redirectUrl;
   // window.close();
</script>
</body>
</html>

通过后台请求重定向

大体流程是,在某一个部署了后台服务的代码中,增加一个Controller接口,该接口通过参数中的env和request,将请求重定向到{env}+{request}接口中,同时附带上自定义和微信回调携带的code和state参数,从而达到转发请求的作用。

后台请求重定向做法

在后台程序中,增加一个Controller接口

@Controller
@RequestMapping("/oauth/wechat")
public class OauthWechatController {
	private static final Logger log = LoggerFactory.getLogger(OauthWechatController.class);

	@Autowired
	private OauthWechatConfiguration oauthWechatConfiguration;

	@RequestMapping(value= "/redirect" , method = RequestMethod.GET)
	@ResponseBody
	public void  redirect(HttpServletRequest request, HttpServletResponse response) throws Exception {
		String requestUrl = request.getParameter("request");
		String code = request.getParameter("code");
		String state = request.getParameter("state");
		String env = request.getParameter("env");
		String platform = request.getParameter("platform");
		log.info("wechat授权跳转参数,env:"+env+",requestUrl:"+requestUrl+",code:"+code+",state:"+state);
		String redirectUrl = oauthWechatConfiguration.getRedirectProdUrl();
		if("dev".equals(env)){
			redirectUrl = oauthWechatConfiguration.getRedirectDevUrl();
		}else if("test".equals(env)){
			redirectUrl = oauthWechatConfiguration.getRedirectTestUrl();
		}else if("pre-prod".equals(env)){
			redirectUrl = oauthWechatConfiguration.getRedirectPreProdUrl();
		}
		String url = redirectUrl+requestUrl+"?platform="+platform+"&code="+code+"&state="+state;
		log.info("wechat授权跳转地址为:"+ url);
		response.sendRedirect(url);
	}
@Configuration
@ConfigurationProperties(prefix = "oauth.wechat")
public class OauthWechatConfiguration {
	private String redirectDevUrl;
	private String redirectTestUrl;
	private String redirectPreProdUrl;
	private String redirectProdUrl;
	private String appId;
	private String appSecret;
	private String env;
	
	//setter and getter...
}

application.yml

oauth:
    wechat:
      redirectDevUrl: http://localhost:4201
      redirectTestUrl: http://192.168.1.10:30080
      redirectPreProdUrl: http://192.168.1.20:30080
      redirectProdUrl: https://admin.loooswc.cn
      appId: xxxxxxxxxx
      appSecret: xxxxxxxxxx
      env: dev # dev研发 test测试 pre-prod准生产 prod生产

微信授权回调域填写admin.loooswc.cn
在这里插入图片描述
调用请求时redirect_url填写https://admin.loooswc.cn/oauth/wechat/redirect.do?env=dev&request=/oauth/wechat/login.do,当然是通过urlEncode处理过的。

这样就可以实现一个授权回调域对多个域名有效的效果了

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个springboot整合微信扫码登录的示例: 1. 首先,在微信公众平台上创建一个应用,并获取到AppID和AppSecret。 2. 在Spring Boot项目中添加以下依赖: ``` <dependency> <groupId>com.github.binarywang</groupId> <artifactId>weixin-java-mp</artifactId> <version>3.4.</version> </dependency> ``` 3. 在application.properties文件中配置AppID和AppSecret: ``` wechat.mp.appId=your_app_id wechat.mp.secret=your_app_secret ``` 4. 创建一个Controller,用于处理微信扫码登录的请求: ``` @RestController @RequestMapping("/wechat") public class WechatController { @Autowired private WxMpService wxMpService; @GetMapping("/login") public String login(HttpServletRequest request) throws WxErrorException { String redirectUrl = "http://your_domain.com/wechat/callback"; String state = UUID.randomUUID().toString(); String url = wxMpService.oauth2buildAuthorizationUrl(redirectUrl, WxConsts.OAuth2Scope.SNSAPI_USERINFO, state); return "redirect:" + url; } @GetMapping("/callback") public String callback(HttpServletRequest request) throws WxErrorException { String code = request.getParameter("code"); WxMpOAuth2AccessToken accessToken = wxMpService.oauth2getAccessToken(code); WxMpUser user = wxMpService.oauth2getUserInfo(accessToken, null); // TODO: 处理用户信息 return "success"; } } ``` 5. 在启动类中添加以下代码,初始化WxMpService: ``` @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Bean public WxMpService wxMpService() { WxMpService wxMpService = new WxMpServiceImpl(); wxMpService.setWxMpConfigStorage(wxMpConfigStorage()); return wxMpService; } @Bean public WxMpConfigStorage wxMpConfigStorage() { WxMpInMemoryConfigStorage configStorage = new WxMpInMemoryConfigStorage(); configStorage.setAppId("your_app_id"); configStorage.setSecret("your_app_secret"); return configStorage; } } ``` 以上就是一个简单的springboot整合微信扫码登录的示例,希望对你有帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值