分享 微信内置浏览器如何获得 openid?

xiaoronglv · 2014年01月26日 · 最后由 ruby_sky 回复于 2015年12月10日 · 73373 次阅读

今天关注了@miclle 开发的微信公众帐号:「健康一点」

里面有几个很酷的功能碉堡了,但是我不知道如何实现的,希望作者能剧透一下。

点击 view 类型的自定义菜单后(基本信息),微信客户端会打开该用户的基本信息。

我查看了微信的官方文档,view 类型的自定义菜单是 get 请求,按道理无法获得用户的 openid。拿不到 openid 如何展示用户的基本信息?

可以在微信内置的浏览器里收藏食物

不知道作者是如何在微信的浏览器中拿到 openid 的。

微信接口里有的,在花了 300 块通过认证后的高级接口里,‘网页授权获取用户基本信息’这里有提到

通过两次跳转后拿到 openid 然后放到 session 中;要注意的是,我没有通过这个接口去拿用户其他的信息 (因为这个需要弹出授权界面),要获取用户其他信息,可以通过‘获取用户基本信息’这个接口异步去做

http://mp.weixin.qq.com/wiki/index.php?title=%E7%BD%91%E9%A1%B5%E6%8E%88%E6%9D%83%E8%8E%B7%E5%8F%96%E7%94%A8%E6%88%B7%E5%9F%BA%E6%9C%AC%E4%BF%A1%E6%81%AF

正好这几天在公司也做了这个功能,用了 omniauth,封装好了的~ #2 楼 @miclle 的方案适合熟手。 推荐用@blankyao写的这个,这个也写的比较好,第一次用很方便。 https://github.com/blankyao/omniauth-weixin

很酷。

这个接口幸好没有访问次数限制。

#3 楼 @mingyuan0715 封装好的那个可以直接用么?调试了好几次无果自己写了个

#5 楼 @dddd1919 他是通过路由初始化调用 omniauth,路由得按照规范来,类似这样的:/auth/weixin 这个地方是坑点,我研究了半天才搞明白,然后就顺了~

我的方法是,在自定义按钮上就带了 2 楼获取 code 的地址,这样实际上进入到自己的网站就带了 code,然后 get openid 就行了。我写了个类 https://github.com/SpecialCyCi/WeixinAdvancedInterface/blob/master/lib/weixin_oauth.rb

配置好 appid,secret 后,获取 code 后,调用

openid = WeixinOauth.instance.get_openid(params[:code]) if params[:code]

就行了

#6 楼 @mingyuan0715 可能哦,没看明白用法,还是自己写得更快一点

没有人尝试用 cookie 吗?

#7 楼 @special 这样做每次都会去 https://open.weixin.qq.com/... 如果会话中已以有了 openid 其实是不再需要去获取 code 及 openid

#1 楼 @miclle 获取用户信息时可以在和公众号信息交互时或者网页授权的方式获取,目前也就这两种,但是我看南派三叔的服务号时,即没有网页授权,也没有和用户交互,就能获取到,谁能帮忙解释一下。

#11 楼 @spiderxu 是不是传说中的内部高级接口?就像‘微信彩票’ ‘招商银行’... 不知道啊,同求解释

#12 楼 @miclle 貌似是,南派三叔号的开发者是比特海公司,据说和微信有着不一般的关系。

#10 楼 @miclle 也是,马上改改,谢谢指教~

15 楼 已删除

楼上各位,使用 cookie 可以吗?下次调用时,直接从 cookie 中拿数据。

cookies[:openid] = @user.openid

我好脑残,openid 需要加密,应该放到 session 中。

如果不从微信中的浏览器中访问这个链接 会报 该链接无法访问,请稍后再试 这个该怎么破

#2 楼 @miclle 使用你的这个方法成功获得 openid 了!不过在测试的稍后,我写了这句 p "I get the session[:openid]" ,但是 看 ngnix 日志 出现了 App 15327 stdout: "I get the openid " App 15320 stdout: "I get the openid my_openid" . 第一次打印空的,第二次把 openid 打印出来了,请问为什么会这样输出两次呢?我只写了一个 p 的输出操作,感谢!

#19 楼 @pathbox 好久没有搞微信了,你自己找找原因

最近在用 Tower (https://tower.im), 如果在它们网站通过关注微信号(不是用户授权)实现账户绑定后,在他们公众号里就可以直接登录网站用户界面了(也没用任何授权提示),所以怀疑它们在整个过程中没有用 auth 机制 (有没有 Tower 的开发人员可以解释一下呢?)。 是不是没有开通 300 块的高级接口认证,就完全没有可能通过链接跳转 (VIEW) 实现微信端用户信息与网站用户的关联 (但是 tower 在微信移动客户端无缝对接网站用户又是如何实现的呢)?

自己尝试了一下,虽然后台在用户点击后可以看到用户 openid, 但是没有办法让跳转的 URL 也知道这个 openid 信息。

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[FromUser]]></FromUserName>
<CreateTime>123456789</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[VIEW]]></Event>
<EventKey><![CDATA[www.qq.com]]></EventKey>
</xml>

微信端使用 oauth 也能对已经关注的用户实现无缝衔接

#2 楼 @miclle

# 如果code参数为空,则为认证第一步,重定向到微信认证
if code.nil?
  redirect_to "https://open.weixin.qq.com/connect/oauth2/authorize?appid=#{Weixin::APP_ID}&redirect_uri=#{request.url}&response_type=code&scope=snsapi_base&state=#{request.url}#wechat_redirect"
end

这里的 redirect_to 应该用 return,直接用 redirect_to 貌似无法跳转!

# 如果code参数为空,则为认证第一步,重定向到微信认证
if code.nil?
  return request_for_code! request.url
end

#23 楼 @imconfused 一年多没搞微信开发了,微信开发可以问下 @ruby_sky

#24 楼 @miclle 谢邀;😄 @imconfused 微信获取 openid,主要是授权:oauth2。 场景是任何进入 mobile 页面,都获取 openid,在使用 weixin_authorize 的基础下,我是这么干的:

application_controller.rb

class ApplicationController < ActionController::Base
  before_action :invoke_wx_auth
  before_action :get_wechat_sns, if: :is_wechat_brower?

  private
   # 调用微信授权获取openid
  def invoke_wx_auth
    if params[:state].present? || !is_weixin_request? \
      || session['openid'].present? || session[:user_id].present? 
      return # 防止进入死循环授权
    end
    if params["need_wx_auth"].present?
      # 生成授权url,再进行跳转
      sns_url =  $wechat_client.authorize_url(request.url)
      redirect_to sns_url and return
    end
  end

  # 在invoke_wx_auth中做了跳转之后,此方法截取
  def get_wechat_sns
    # params[:state] 这个参数是微信特定参数,所以可以以此来判断授权成功后微信回调。
    if session[:openid].blank? && params[:state].present?
      sns_info = $wechat_client.get_oauth_access_token(params[:code])
      Rails.logger.debug("Weixin oauth2 response: #{sns_info.result}")
      # 重复使用相同一个code调用时:
      if sns_info.result["errcode"] != "40029"
        session[:openid] = sns_info.result["openid"]
      end
    end
  end
end

这里只负责获取微信的 openid,跟用户绑定,我的建议是用户在登录成功、注册功能后,都进行绑定。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号