ruby 微信分享

微信分享比较简单,麻烦点的地方就是生成签名, 同时要特别记住签名的url, 我做的时候遇到一个情况,就是第一次分享正常,分享后再转发就不行啦,我就是因为url不对造成的,因为分享后微信会在链接后加上标识,比如分享给朋友会加上?from=singlemessage, 开始我是直接使用rails生成的url: mobile_article_path, 这个url就固定死了, 导致分享后的链接于这个url不一样,所以签名生成错误,再次转发也不行了。


url = request.url
      if url.nil?
        url = mobile_article_path(params[:id])
        @url = 'https://' + ENV.fetch('DEFAULT_HOST') + url
      else 
        @url = url
      end

      wechat_api = WechatApi::Wechat.new
      @jsapi_config = wechat_api.get_jsapi_signature(@url)

微信js:

<script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
<script type="text/javascript">
  wx.config({
    debug: false,
    appId: '<%= @jsapi_config[:appid] %>', // 必填,公众号的唯一标识
    timestamp: <%= @jsapi_config[:timestamp] %>, // 必填,生成签名的时间戳
    nonceStr: '<%= @jsapi_config[:noncestr] %>', // 必填,生成签名的随机串
    signature: '<%= @jsapi_config[:signature] %>',// 必填,签名
    jsApiList: ['onMenuShareTimeline', 'onMenuShareAppMessage'] // 必填,需要使用的JS接口列表
  });

  var share_data = {
    title: '家具头条|<%= @article.title %>', // 分享标题
    desc: '<%= @article.meta_description %>', // 分享描述
    link: '<%= @url %>', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
    imgUrl: '<%= show_pic(@article.image, w: 300, h: 300) %>', // 分享图标
    success: function () {
      // 用户确认分享后执行的回调函数
      // alert('<%= @article.title %>');
    },
    cancel: function () {
      // 用户取消分享后执行的回调函数
      // alert('<%= @article.title %>');
    }
  }
  wx.ready(function(){
    wx.onMenuShareTimeline(share_data);

    wx.onMenuShareAppMessage(share_data);
  });
  wx.error(function(res){
    // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
    // alert(res);
  });
</script>


签名:

# 获取
    def get_jsapi_ticket 
      now = Time.now
      now = now.to_i
      client = HttpClientWechat.new(@access_token_url, @timeout, @skip_verify_ssl)

      data = client.get_json('jsapi_ticket.json')
      expire_seconds = data.blank? ? '' : data['expire']
      jsapi_ticket = nil


      # 过期时间为空或小于记录的时间
      if expire_seconds.blank? || expire_seconds < now
        access_token = get_access_token
        client = HttpClientWechat.new(@jsapi_ticket_url, @timeout, @skip_verify_ssl)
        get_info = client.get('getticket', params: { access_token: access_token , type: 'jsapi' })

        unless get_info['ticket'].nil?
          jsapi_ticket = get_info['ticket']
          expire_seconds = now + 7000
          data = {
            jsapi_ticket: jsapi_ticket,
            expire: expire_seconds
          }
          data_json = JSON.generate(data)
          client.set_json('jsapi_ticket.json', data_json)
        end
      else
        jsapi_ticket = data['jsapi_ticket']
      end

      jsapi_ticket
    end

    # jsapi 签名算法
    def get_jsapi_signature(url)
      jsapi_ticket = get_jsapi_ticket
      res = nil
      if jsapi_ticket
        noncestr = create_noncestr
        timestamp = Time.now.to_i
        jsapi_config = {
          noncestr: noncestr,
          jsapi_ticket: jsapi_ticket,
          timestamp: timestamp,
          url: url
        }
        signature = sign_param(jsapi_config)
        res = {
          appid: @app_id,
          timestamp: timestamp,
          noncestr: noncestr,
          signature: signature,
        }
      end

      res
    end

    # 自定义菜单
    def create_menu

    end

    private

    #随机数生成算法
    def create_noncestr
      len = 30
      chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
      newpass = ""
      1.upto(len) { |i| newpass << chars[rand(chars.size-1)] }
      newpass
    end

    #生成签名[排序,url参数格式,拼接key,机密]
    def sign_param(param)
      param = param.sort{ |a,b| a.to_s <=> b.to_s }.to_h

      format = []
      param.each_with_index do |value|
        format << "#{value[0]}=#{value[1]}"
      end

      Digest::SHA1.hexdigest("#{format.join('&')}").upcase
    end

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值