首页 >> 网页技术 > 编程技术 >> 详细内容
编程技术 >> 正文
个人订阅号实现网页获取用户openid(asp版)
日期:2018/8/9 

微信公众平台的账号分为服务号、订阅号、企业号3种类型。而个人类型的订阅号在开发功能上有很多的限制。比如自定义菜单、oauth2.0接口等。其中,自定义菜单功能可以通过命令交互

的方式来代替。
OAuth2.0接口可以实现用户通过微信公众号访问网页的时候获取用户的openid、个人信息等。但是个人订阅号微信平台不提供这个接口,其实很多时候我们只需要得到用户的openid就可以

了。
我们知道,用户在通过微信平台和我们进行消息交互的时候,我们通过微信平台传来的xml数据包进行数据获取。这个xml数据包包含有一个FromUserName的参数,就是指的用户的openid。

于是我们可以通过这一原理来传递用户访问网页时候的openid。
以下是具体步骤:
一、用户提出获取网页网址的请求。
我们的账户类型是订阅号,无法通过菜单来实现。所以只能通过被动的方式传递信息。用户发送“查询网址”的消息给微信平台后,微信平台顺手将消息封装成一定格式的xml传递给我们的

服务器。我们的服务器就得到这个“查询网址”的命令,知道用户想获取网页地址。于是随机生成一个密码,把这个密码存入数据库中。接下来将密码和openid加密后作为网页的参数和网

址一起回传给微信平台,微信平台再将消息回复给用户。过程如下图所示:

 


二、用户点击网址
用户点击这个带有加密参数的网址,服务器网页接收到用户的请求后,先将参数进行解密,分解为openid和密码2个部分。首先验证密码是否正确,如果不正确,则拒绝访问,要求用户重新回复“查询网址”命令生成网址。如果密码正确,则密码失效,重新生成一个密码写入session和数据库,接下来就通过session进行验证,并且我们也得到了用户的openid。密码一次失效机制防止没关注的用户访问。如下图:


三、存在的问题
我们通过密码和session来验证用户,openid通过微信平台的消息互发来获取。要访问网址要求用户必须和我们的消息交互程序交互一次,以获得用户的openid和密码,密码一次失效的机制也能防止用户转发消息来冒充身份。那么,这就存在一个问题,如果用户通过合法的关注渠道得到网址后,不去访问网址,直接将网址转发给别人,那么我们获取到的openid就不是这个用户本身。但是这可以算作是一种授权行为,因为关注的用户有转发的动作。


四、asp版部分代码
1、生成网址:
<%
'得到用户的openid和获取网址的意图,方法参考:http://www.yufeng.org.cn/view_article.asp?id=26

set rsw=server.CreateObject("adodb.recordset")
rsw.open "select webmima from [users] where weixinhao='"&weixinhao&"'",conn,1,3 'weixinhao即用户的openid,通过xml数据获取。
if rsw.recordcount<1 then
 stringback="nouser"
else
 randomize()
 strrnd=int(10000000+89999999*rnd()) '生成8位随机密码写入数据库中
 rsw("webmima")=cstr(strrnd)
 rsw.update
 strrnd=base64(weixinhao&strrnd)  '将openid和mima用base64加密,也可以自定义加密解密算法
 stringback="请点击:http://www.yufeng.org.cn/nav.asp?authcode="&server.URLEncode(strrnd)&"(一次有效,再次访问须重新生成)" '将加密后的字符作为参数加入网

址中,用URLEncode可以将一些保留url字符编码
end if
rsw.close
set rsw=nothing
'接下来是回传给微信平台的代码,参考:http://www.yufeng.org.cn/view_article.asp?id=26

%>
2、身份验证:
<%
session("weixinhao")=sqlcheck(session("weixinhao"))
session("webmima")=sqlcheck(session("webmima"))
if session("weixinhao")="" or session("webmima")="" then
 '进入系统,首先验证session是否存在,以及是否合法。
 '如果session不存在,则需要看是否有authcode被request到,如果有request到,则通过以下代码进行验证
 authcode=request("authcode")
 if authcode="" then
  founderr=true
 else
  authcode=base64jiemi(authcode) 'base64解密,也可以自定义加密解密算法
  authcode=sqlcheck(authcode) '对传递来的参数进行过滤,防止sql注入等恶意代码
  if len(authcode)<>36 then  'openid有28位,我们采用的密码是8位随机码,所以这里判断是否等于36
   founderr=true
  else
   weixinhao=left(authcode,28) '分别获得openid和随机密码
   webmima=right(authcode,8)   
   set rs=server.CreateObject("adodb.recordset")
   rs.open "select webmima from [users] where weixinhao='"&weixinhao&"' and webmima='"&webmima&"'",conn,1,3
   if rs.recordcount>0 then
    '如果验证成功,则当前webmima失效,重新生成webmima写入数据库和session中
    isequ=true
    do while isequ
     '这个循环用来保证重新生成的webmima不能和原来的webmima相同
     randomize()
     strrnd=int(10000000+89999999*rnd())
     if strrnd<>webmima then
      webmima=strrnd
      exit do
     end if
    loop
    rs("webmima")=webmima '将生成的密码重新写回数据库,即密码一次失效。
    rs.update
    session("weixinhao")=weixinhao '并且将openid和webmima写入session中,用来在其他页面中验证。
    session("webmima")=webmima
   else
    founderr=true
   end if
   rs.close
   set rs=nothing
   
  end if
 end if
else
 founderr=true
end if
if founderr then
 '返回出错信息,让用户重新获取
 response.write "请通过微信回复“查询网址”重新生成网址后访问。"
else
 '后续处理代码
end if
%>