前端开发第三方分享/登录功能备忘(facebook、weibo、QQ、weixin微信好友或者朋友圈)

##前端开发第三方分享【/三方登录】功能备忘(facebook脸书、Whatsapp、weibo、QQ、weixin好友或者朋友圈)

平台支持域名备案切换域名调整平台名称注意事项🇭🇰境外文档地址
微信手机端H52个不需要支持2个域名,不用调整微信公众平台手机端和pc端注意用户二合一,通过unionId; 微信分享和登录都支持支持微信公众平台—>微信网页开发; 🔍网页授权、分享关键字
PC端微信登录仅仅只能配置一个域名,必须修改1个不需要支持一个微信开放平台网页应用,切换环境必须修改配置,否则报错:redirect_uri参数错误,配置地址:应用详情->授权回调域;支持香港注册公司;pc扫描登录支持、pc分享其实是扫二维码,直接打开二维码。支持微信开放品台-网站应用微信登录
QQ多个必须,除非发邮件说明是国际域名证书 、公司营业执照支持多个回调地址,必须配置到具体的页面配置好,不用修改常见问题,账号没有开通。或者 需要备案比较麻烦,需要配置回调地址,否则:redirect uri is illegal(100010) QQ互联加强网站应用回调地址校验-QQ互联-OpenAPI调用说明_OAuth2.0
sina3个+不需要不用,支持多个回到地址新浪开发平台支持相关个人公司微博开放平台-授权机制
facebookn个不需要不用注册账号都可以facebook官网开发者不用注册公司,当然需要扶梯一把支持分享调试器facebook爬虫策略
WhatsAppn个不需要不用注册账号都可以不用注册公司,当然需要扶梯一把支持HTML5网页点击分享到WHATSAPP

前端分享有很多,常见有(facebook、weibo、QQ、weixin)

另外,在手机浏览器里面,facebook、weibo是直接打开他们的网站的。微信朋友圈、微信好友、QQ好友都是粘贴复制的。

网站分享到facebook

一、 facebook分享

1.1. facebook分享

facebook全球最大的社交网络平台,当然大陆的话是访问不了的,需要自己的解决。当经常有项目或者香港、澳门的项目或者稍微有点国际化的项目也需要使用facebook.

  • facebook分享其实特别简单,第一不用注册开发者账号也可以正常使用。【一般就弹框打开一个链接,就可以分享了,pc和手机端是一样的】
  • facebook风向出来的图片、文字、描述,需要在页面顶部meta标签里面说明。当然动态网站就需要自己想办法,比如vue、react写的页面,要么页面进行静态化、要么就后台走一个代理(判断是facebook排虫访问,就动态返回一个页面)。
#这里是java代码,就网页进行代理一次;  
# 1:用户分享链接到facebook。
# 2:facebook 爬虫 访问我们系统,
# 3:当我们系统的代理nginx发现是是facebook爬虫访问话,我们重定向到 这个代理方法。
# 4:后台java 动态访问一个网页
/**
     * 给动态facebook爬虫做代理
     * 给动态网页做代理,比如网页分享到facebook的话,需要从【源码】读取 title、img,但是这些都是读取的源码 动态网页 vue、react 因此无法更改源码,动态更新的没用;
     * 这里后台进行一次代理;这里配合 nginx 进行配置
     * <p>
     * # 如果user_agent是从facebook爬虫过来的; 我们 就 进入代理接口
     * if ($http_user_agent ~* "facebookexternalhit") {
     * ###### proxy  ^/(.*)$  http://127.0.0.1:7777/ redirect;irect;   #这种不能加$uri后缀了,很麻烦,需要同时有两个tomcat
     * rewrite  ^/(.*)$  https://test189.ourslook.com/qcure/proxy?$uri redirect;  #直接302过去 后面不用 增加【?$args】; 会自动增加args的
     * rewrite  ^/(.*)$  $scheme://$host/qcure/proxy?$uri redirect;  #直接302过去; 原始访问地址是:  https://$host/qcurepc/xxx
     * }
     * <p>
     * 网页分享到facebook, 异常简单,甚至 连 appid都不需要的; 网页分享到FACEBOOK  https://www.cnblogs.com/phperlinxinlan/p/10529012.html
     * <p>
     * facebook 爬虫设置nginx设置 https://blog.csdn.net/moliyiran/article/details/54846799
     * https://www.cnblogs.com/phperlinxinlan/p/10529012.html
     * facebook web分享:  源站见评论  https://developers.facebook.com/docs/sharing/reference/feed-dialog
     * facebook 分享的爬虫策略 源站见评论 https://developers.facebook.com/docs/sharing/webmasters/crawler?locale=zh_CN
     * <p>
     * 分享调试器:分享调试器:https://developers.facebook.com/tools/debug/sharing/
     *
     * @return 网页
     */
    @ApiIgnore
    @IgnoreAuthToken
    @ResponseBody
    @RequestMapping(value = "/proxy", produces = "text/html;charset=UTF-8", method = RequestMethod.GET)
    public String proxy(
            @ApiParam("网页的title,字段名:title,选填,默认是项目名称,方便调试") @RequestParam(value = "title", defaultValue = "QCURE", required = false) String title,
            @ApiParam("网页的image,字段名:image,选填,默认这里放一个空图片,方便调试") @RequestParam(value = "image", defaultValue = "https://static.xx.fbcdn.net/rsrc.php/v3/y6/r/hlFyGnljr-d.png", required = false) String image,
            HttpServletRequest request) {
        try {
            //这里对图片进行解码,防止图片是被多次encode之后的,encode之后的路径,可能访问不了
            //这里就先两次解码把,应该不会有问题;如果出问题,后台就不帮前台处理了
            image = EncodeUtils.urlDecode(image);
            image = EncodeUtils.urlDecode(image);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        String emptyHtml = "<!DOCTYPE html>\n" +
                "<html>\n" +
                "<head>\n" +
                "\t<title>@@tilte</title>\n" +
                "\t<title>@@image</title>\n" +
                "\t<meta property=\"og:title\" content=\"@@tilte\" />\n" +
                "\t<meta property=\"og:image\" content=\"@@image\" />\n" +
                "</head>\n" +
                "<body>\n" +
                "\t我是后台转发的内容\n" +
                "</body>\n" +
                "</html>";
        if (XaUtils.isValid(title)) {
            emptyHtml = emptyHtml.replace("@@tilte", title);
        }
        if (XaUtils.isValid(image)) {
            emptyHtml = emptyHtml.replace("@@image", image);
        }
        return emptyHtml;
    }

参考:
网页分享到FACEBOOK【前端看这个文档就够了】
FACEBOOK分享调试器
facebook 分享的爬虫策略 源站见评论

二、 Whatsapp分享

网页不做处理,直接分享到Whatsapp是不显示标题、图片,体验不好;
因此,分享的时候我们需要对网页做处理。

参考:HTML5网页点击分享到WHATSAPP

由于我们做的网站是vue做的动态网站,并且没有做网页静态化,爬取到网页,这数据都是空的;因此需要我们后台做一个代理
<meta name="whatsapp:url" class="share_url" content="http://www.abc.com">
<meta name="whatsapp:title" class="share_title" content="测试分享到whatsapp">

  /**
     * 参考:HTML5网页点击分享到WHATSAPP https://www.cnblogs.com/phperlinxinlan/p/10305376.html
     * 核心:
     * <meta name="whatsapp:url" class="share_url" content="http://www.abc.com">
     *     <meta name="whatsapp:title" class="share_title" content="测试分享到whatsapp">
     *
     * agent:WhatsApp
     *
     * # 如果user_agent是从facebook爬虫过来的; 我们 就 进入代理接口
     * if ($http_user_agent ~* "WhatsApp") {
     * #proxy  ^/(.*)$  http://127.0.0.1:7777/ redirect;irect;   #这种不能加$uri后缀了,很麻烦,需要同时有两个tomcat
     * rewrite  ^/(.*)$  $scheme://$host/qcure/proxy/WhatsApp?$uri redirect;  #直接302过去; 原始访问地址是:  https://$host/qcurepc/xxx
     * }
     *
     *
     * 116.48.97.249 - - [18/Jan/2021:10:53:17 +0800] "GET /qcurepc/level2/283 HTTP/1.1" 200 1325 "-" "WhatsApp/2.20.206.24 A"
     *
     * 12.15.176.108 - - [18/Jan/2021:10:58:07 +0800] "GET /qcure/upload/product/20201119112124868_qan3l.jpg HTTP/1.1" 302 138 "https://www.qcure.com/qcureweb/" "Mozilla/5.0 (Linux; Android 10; LIO-AN00 Build/HUAWEILIO-AN00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.62 XWEB/2693 MMWEBSDK/201201 Mobile Safari/537.36 MMWEBID/2818 MicroMessenger/7.0.22.1820(0x270016A2) Process/toolsmp WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64"
     *
     * @param title
     * @param url
     * @param request
     * @return
     */
    @ApiIgnore
    @IgnoreAuthToken
    @ResponseBody
    @RequestMapping(value = "/proxy/WhatsApp", produces = "text/html;charset=UTF-8", method = RequestMethod.GET)
    public String proxyWhatsApp(
            @ApiParam("网页的title,字段名:title,选填,默认是项目名称,方便调试") @RequestParam(value = "title", defaultValue = "QCURE", required = false) String title,
            @ApiParam("分享图片") @RequestParam(value = "image", defaultValue = "https://static.xx.fbcdn.net/rsrc.php/v3/y6/r/hlFyGnljr-d.png", required = false) String url,
            HttpServletRequest request) {

        try {
            title = EncodeUtils.urlDecode(title);
            title = EncodeUtils.urlDecode(title);
            url = EncodeUtils.urlDecode(url);
            url = EncodeUtils.urlDecode(url);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }


        String emptyHtml = "<!DOCTYPE html>\n" +
                "<html>\n" +
                "\n" +
                "<head>\n" +
                "    <title>@@title</title>\n" +
                "    <meta name=\"image\" content=\"@@url\">\n" +
                "</head>\n" +
                "\n" +
                "<body>\n" +
                "    转发内容\n" +
                "</body>\n" +
                "\n" +
                "</html>";
        if (XaUtils.isValid(title)) {
            emptyHtml = emptyHtml.replace("@@title", title);
        }
        if (XaUtils.isValid(url)) {
            emptyHtml = emptyHtml.replace("@@url", url);
        }
        sysLogService.saveLogManual("sys:系统管理员", "WhatsApp 爬虫 proxy", emptyHtml, null);

        return emptyHtml;
    }

分享成功,如图:
Whatsapp分享示例

三、微博weibo

3.1. 微博必须要有注册好的微博账号

  1. 微博授权及获取信息文档: https://open.weibo.com/wiki/%E6%8E%88%E6%9D%83%E6%9C%BA%E5%88%B6
  2. 新浪授权1:OAuth2/authorize 请求用户授权Token 【会获取到一个code】
  3. 新浪授权2:OAuth2/access_token 获取授权过的Access 【会获取到accesstoken和uid】
  4. 新浪授权3:通过openId、accessToken获取微博信息【获取微博用户信息】
  5. 账号问题,测试环境和正式环境使用的是一套账号,一个账号可以添加超过3个域名
// 微博授权第二步,根据第一步的code换取access-token和uid
    /**
     * @param redirectUri 授权完成之后,重定向的页面;注意,这里的传参,好像只能返回一个参数
     * @param code 微博第一步获取到的code
     * @return
     */
    @IgnoreAuthToken
    @RequestMapping(value = "sina/access_token", method = {RequestMethod.POST, RequestMethod.GET})
    @ApiOperation(value = "微博授权第二步,根据第一步的code换取access-token和uid ", notes = "这里是,新浪授权2:OAuth2/access_token 获取授权过的Access 【会获取到accesstoken和uid】", position = 2)
    public XaResult<String> sinaAuth(
            @ApiParam("回调地址,字段名:redirectUri") @RequestParam(value = "redirectUri") String redirectUri,
            @ApiParam("code,字段名:code") @RequestParam(value = "code") String code
    ) {
        HttpClientSimpleUtil httpClient = HttpClientSimpleUtil.getInstance();
        Map<String, String> params = new HashMap<>();
        params.put("client_id", SINA_APP_KEY);
        params.put("client_secret", SINA_APP_SECRET);
        params.put("redirect_uri", redirectUri);
        params.put("grant_type", "authorization_code");
        params.put("code", code);
        String url = "https://api.weibo.com/oauth2/access_token";
        String response = httpClient.doPostRequest(url, params);
        return new XaResult<String>().setObject(response);
    }
//授权最后一步,根据 获取第三方的openId和accestoken获取第三方的用户信息
/**
     * 第三方登录
     *
     * @see Constant.ThreeAccontType 所有第三方登录类型
     * @see ApiWeappUserController#loginByWxJSCode(String, Integer, Boolean, HttpServletRequest)  微信的注册见
     *
     * @return
     */
    @IgnoreAuthToken
    @RequestMapping(value = "threeLogin", method = {RequestMethod.GET})
    @ApiOperation(value = "第三方授权登录接口,根据openId与accessToken登录", notes = "第三方登录注册用户&生成token", position = 2)
    public XaResult<TbUserVo> threeLogin(
            @ApiParam(value = "access_token,字段名:accessToken") @RequestParam(value = "accessToken") String accessToken,
            @ApiParam(value = "openId,字段名:微信/微博/qq 唯一的ID openId", defaultValue = "openId") @RequestParam(value = "openId") String openId,
            @ApiParam(value = "type,字段名:类型,取值是sinaWeibo、qq, 具体查看常量:Constant.ThreeAccontType , 见接口: /mall/constants/ ", defaultValue = "取值是sinaWeibo") @RequestParam(value = "type") String type
    ) {
        XaResult<TbUserVo> xr = new XaResult<>();

        if (!XaUtils.isValid(accessToken)) {
            return xr.error("accessToken不能为空!accessToken = " + accessToken);
        }
        if (!XaUtils.isValid(openId)) {
            return xr.error("openId不能为空!openId = " + openId);
        }
        if (!Constant.ThreeAccontType.isConstantVal(type)) {
            return xr.error("threeLogin方法请输入有效的type, type = " + type +"!");
        }

        TbUserEntity user = null;
        TbUserVo userVo = new TbUserVo();
        if (Constant.ThreeAccontType.QQ.equalsIgnoreCase(type)) {
            //qq
            user = userService.queryByqqAcc(openId);
            if (XaUtils.isEmpty(user)) {
                //不存在则获取信息进行存储
                user = getQqInfo(accessToken, openId);
                userService.save(user);
            }
        } else if (Constant.ThreeAccontType.SINA_WEIBO.equalsIgnoreCase(type)) {
            //微博
            user = userService.queryByWeiboAcc(openId);
            if (XaUtils.isEmpty(user)) {
                //不存在则获取用户信息并进行存储
                user = getWeiboInfo(accessToken, openId);
                userService.save(user);
            }
        } else {
            return xr.error("不支持的type, type = " + type);
        }

        if (XaUtils.isNotEmpty(user)) {
            Map<String, Object> tokenMap = tokenService.createToken(user.getUserId(), false);
            beanMapper.copy(user, userVo);
            userVo.setToken(tokenMap.get("token") + "");
        }

        return xr.setObject(userVo);
    }

    /**
     * QQ登录根据access_token与openId获取qq用户信息
     *
     * @param accessToken
     * @param openId
     * @return
     */
    private TbUserEntity getQqInfo(String accessToken, String openId) {
        TbUserEntity user = new TbUserVo();
        String url = "https://graph.qq.com/user/get_user_info?oauth_consumer_key="
                + QQ_APP_ID + "&access_token="
                + accessToken + "&openid=" + openId + "&format=json";
        HttpClientSimpleUtil httpClient = HttpClientSimpleUtil.getInstance();
        String response = httpClient.doGetRequest(url);
        JSONObject jsonObject = JSON.parseObject(response.replaceAll("\n", ""));
        user.setName(jsonObject.getString("nickname"));
        user.setHeadPortraitImg(jsonObject.getString("figureurl_qq_2"));
        user.setStatus(Constant.Status.valid);
        user.setCreateTime(LocalDateTime.now());
        user.setQqAcc(openId);
        user.setUserTypes(Constant.UserTypes.USER_NORMAL_1);
        return user;
    }

    /**
     * 通过openId、accessToken获取微博信息
     * @param accessToken
     * @param openId
     * @return
     */
    private TbUserEntity getWeiboInfo(String accessToken, String openId){
        TbUserEntity user = new TbUserEntity();
        String url = "https://api.weibo.com/2/users/show.json?access_token=" + accessToken + "&uid=" + openId;
        HttpClientSimpleUtil httpClient = HttpClientSimpleUtil.getInstance();
        String response = httpClient.doGetRequest(url);
        JSONObject jsonObject = JSON.parseObject(response.replaceAll("\n", ""));

        user.setName(jsonObject.getString("screen_name"));
        user.setHeadPortraitImg(jsonObject.getString("profile_image_url"));
        user.setStatus(Constant.Status.valid);
        user.setCreateTime(LocalDateTime.now());
        user.setSinaAcc(openId);
        user.setUserTypes(Constant.UserTypes.USER_NORMAL_1);
        return user;
    }

微博开放平台

四. weixin公众平台(手机端)分享

微信中国最大的社交平台, 微信可以同时配置两个地址,即测试环境和正式环境可以使用一个账号
公众号设置-安全&jssdk安全&授权登录

五. weixin开放平台(PC)登录、分享

微信中国最大的社交平台, 微信可开放平台的授权地址只能配置一个,修改域名,需要重新配置。

六. QQ互联平台

腾讯开发平台是腾讯总体对外所有开发平台的集合,包含应用开放平台就是应用宝相关、**QQ互联平台[开放]**就是QQ登录和分享的能力、微信公众号、微信开发平台等

七. 移动端使用NativeShare.js进行分享

手机端的h5页面分享手机端的分享能力有限,自己开发比较麻烦,这里接入插件NativeShare.js,但插件目前实践中,支持持UC*和QQ**,其他浏览器都不支持,不支持的浏览器,提示用户自己去粘贴;

  1. 目前仅仅支持UC和QQ
  2. 不支持的浏览器,无法弹出自己的弹框,需要自己开发一个页面,点击分享,进行粘贴链接地址;
  3. 在微信里面,如果分享,直接提示 在浏览器中打开,或者 在右上角用微信自带的分享能力。 注意微信自带分享,前端开发也要开发的,不处理的话,可能分享图片、连接全是错误的。
    QQ和UC浏览器可以弹出自己的框框
    其他浏览器自己开发一个页面,自己写开发事件,微博、facebook直接分享到web自己开发,其他QQ等就粘贴
    不支持的浏览器-粘贴到粘贴板

八. 国际域名证书

GoDaddy注册的域名,在大陆不好备案,国内需要国际域名证书。
類似,打過去等了很久才有人接,然後她叫我在godaddy公眾號裡面下載證書就可以了…[偷笑]。godaddy有微信公眾號,太方便了

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dazer007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值