微信公众号开发Django-网页受权

原文连接html

对于基础的微信公众号开发,网页受权,JSSDK,图片处理应该是最重要的三部分了
根本上也是按照文档开发,技术含量并不高。

(选Django=不少权限控制模块已经作好了,比较省力)python

在开始以前极力推荐内网穿透的各类工具,能够实时调试公众号
推荐本身搭建,能够自定义域名,传输也放心
https://github.com/inconshreveable/ngrok
https://github.com/fatedier/frp

不想手动实现所有的能够参考 WeRoBot
一开始就打算用这个,省力一下,不过它也有部分接口没有实现
改着改着,致使到最后。。。。不经意地本身实现了'小封装'
不过只用一些基础接口仍是直接用框架比较方便git

网页受权,直接摘抄官方文档:github

  • 第一步:用户赞成受权,获取code
  • 第二步:经过code换取网页受权access_token
  • 第三步:刷新access_token(若是须要)
  • 第四步:拉取用户信息(需scope为 snsapi_userinfo)
  • 附:检验受权凭证(access_token)是否有效
# xgc.wechat.py部分

token=os.environ.get('TOKEN') # 文末会提到
app_id=os.environ.get('APP_ID')
app_secret=os.environ.get('APP_SECRET')
redirect_url = os.environ.get('REDIRECT_URL')
state = os.environ.get('STATE')
#网页受权部分
web_get_code = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&state=%s&scope='%(app_id,redirect_url,state)
web_get_fan_info = 'https://api.weixin.qq.com/sns/userinfo?access_token='
web_check_access_token = 'https://api.weixin.qq.com/sns/auth?access_token='
web_get_access_token = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&grant_type=authorization_code&code='%(app_id,app_secret)

# views.py部分

class web_authorization(View):

    def get(self, request):
        from xgc.wechat import web_get_code, web_get_fan_info,web_get_access_token,web_check_access_token
        code = request.GET.get("code", "")
        if not code:
            return HttpResponse("非法访问")
        requests_web_get_access_token_result = requests.get(web_get_access_token+code).json()
        if 'errmsg' in requests_web_get_access_token_result.keys():
            return HttpResponseRedirect(web_get_code+'snsapi_base#wechat_redirect')
        if cache.has_key('web_access_token'):
            web_access_token = cache.get('web_access_token')
        else:
            web_access_token = requests_web_get_access_token_result['access_token']
            cache.set('web_access_token',web_access_token,110*60) #下面会有说明
        fan_openid = requests_web_get_access_token_result['openid']
        # 这部分检验对于缓存来讲是多余的,可是你若是担忧缓存出问题,能够再次检验一波
        # check_access_token = requests.get(web_check_access_token+'%s&openid=%s'%(web_access_token,fan_openid)).json()
        # if check_access_token['errcode']!=0:
        #     return HttpResponseRedirect(web_get_code+'snsapi_base#wechat_redirect')
        scope = requests_web_get_access_token_result["scope"]
        if scope == "snsapi_userinfo":
            fan_info = requests.get(web_get_fan_info+'%s&openid=%s&lang=zh_CN' % (web_access_token, fan_openid))
            fan_info.encoding = 'utf-8'
            fan_info = fan_info.json()
            FansProfile.create_fan(fan_info)
        check_openid = FansProfile.objects.filter(openid=fan_openid).first()
        if not check_openid:
            return render(request, 'register.html', {'url': web_get_code+'snsapi_userinfo#wechat_redirect','header':'认证提示','text':'你还未进行信息认证,请进行第一次认证'})
        response = HttpResponseRedirect('index')
        response.set_cookie('fanid',check_openid.id,3600)
        return response

code

这里我直接在公众号菜单部分设置了引导url
这里设置成base受权,是由于在代码里添加了认证部分
用户第一次认证后咱们就能保存用户基本信息了,下一次就不必在进行userinfo受权了
并且静默受权用户体验也更好点
{
    "type": "view",
    "name": "申请活动",
    "url": wechat_get_code+'snsapi_base#wechat_redirect',
    "key": "test_4"
}

access_token

如文档所说,在获取code以后直接请求换取咱们须要的access_tokenweb

if cache.has_key('web_access_token'):
    web_access_token = cache.get('web_access_token')
else:
    web_access_token = requests_web_get_access_token_result['access_token']
    cache.set('web_access_token',web_access_token,110*60)

代码中采用了缓存策略,微信中不少token是有请求次数限制的
并且都有一段失效期,缓存token是一个明智的选择
具体的缓存下面会提到redis

refresh_token

换取access_token的同时微信会返回一个refresh_token
用于对access_token的刷新,不过个人代码中没有采用
而是直接采起了从新受权数据库

snsapi_userinfo

在第一次受权的时候咱们检测数据库中是否有此用户的认证记录
若是没有则跳转引导用户进行userinfo受权

其中咱们须要注意的是这里微信服务器返回的数据没有指明数据编码类型致使直接读取会出现乱码
咱们能够指定response编码进行转码
具体解释推荐这个帖子https://www.v2ex.com/t/172276django

if scope == "snsapi_userinfo":
    fan_info = requests.get(web_get_fan_info+'%s&openid=%s&lang=zh_CN' % (web_access_token, fan_openid))
    fan_info.encoding = 'utf-8'
    fan_info = fan_info.json()
    FansProfile.create_fan(fan_info)

PS:set_cookie是由于我没有把粉丝的模型继承Django的user模型
不能使用自身的auth模块,后期提交表单,上传图片又须要知道是谁上传的
就采用记录用户id到cookie的方式json

关于缓存

此处采用Redis的方式
首先Django的settings.py引入缓存配置api

CACHES = {
    'default': {
        'BACKEND': 'django_redis.cache.RedisCache', #本地文件缓存
        'LOCATION': '127.0.0.1:6379',
        'TIMEOUT': 600,
        'OPTIONS': {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
            "IGNORE_EXCEPTIONS": True,
        }
    }
}
而后咱们就能够经过引入from django.core.cache import cache模块
进行一些基本的操做,好比下面
# 设置web_access_token键值
# 有效期110*60s,即110min
cache.set('web_access_token',web_access_token,110*60)

官方文档

os.environ.get('')

这里获取根目录.env文件的各类配置
能够针对部分秘密token,app_id进行单独配置

由此创建虚拟环境推荐工具Pipenv而不是经常使用的virtualenv等~默认支持.env的导入

相关文章
相关标签/搜索