Wechat official account Django- web page licensing date: 2018-06-21 17:02:03

For the basic wechat public number development, web page authorization,JSSDK, image processing should be the most important three parts of the document is fundamentally developed, the technical content is not high.

(Django= A lot of permission control modules are already in place to save effort)

Before the beginning of highly recommended Intranet penetration of various tools, can be real-time debugging public number recommended to build their own, can customize the domain name, transmission is assured github.com/inconshreve… Github.com/fatedier/fr…

WeRoBot was intended to use this from the beginning to save effort, but it also had some interfaces that were not implemented. You inadvertently implement ‘mini-encapsulation’ yourself, but it’s easier to just use the basic interface and use the framework directly

Web page authorization, direct excerpts from official documents:

  • Step 1: The user agrees to authorize and gets the code

  • Step 2: Exchange web authorization access_token with code

  • Step 3: Refresh the access_token (if necessary)

  • Step 4: Pull user information (scope is snsapi_userinfo)

  • Attachment: Verify the validity of access_token

# XGC. Wechat. Py part

token=os.environ.get('TOKEN') # Will be mentioned at the end of this article
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 page authorization section
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 part

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("Unauthorized access")
        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) # There are instructions below
        fan_openid = requests_web_get_access_token_result['openid']
        This part of the check is redundant for the cache, but you can check the wave again if you are worried about the cache
        # 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':'Authentication Tips'.'text':'You have not authenticated the information, please authenticate it for the first time'})
        response = HttpResponseRedirect('index')
        response.set_cookie('fanid',check_openid.id,3600)
        return response
Copy the code

code

In this case, I directly set the boot URL in the public account menu section and set it to base authorization, because we have added the authentication part in the code. After the first authentication, we can save the basic information of the user, so there is no need to do userInfo authorization next time and the user experience is better with silent authorization

{
    "type": "view"."name": "Application Activities"."url": wechat_get_code+'snsapi_base#wechat_redirect'."key": "test_4"
}
Copy the code

access_token

As stated in the documentation, we request the access_token we need directly after we get the code

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)
Copy the code

Caching strategy is adopted in the code. Many tokens in wechat have a limit on the number of requests and all have an expiration period. Caching tokens is a wise choice

refresh_token

When exchanging the access_token, wechat will return a refresh_token for refreshing the access_token. However, I did not use the refresh_token in my code, but directly adopted reauthorization

snsapi_userinfo

During the first authorization, we check whether there is an authentication record of the userin the database. If not, we redirect the user to userInfo authorization

What we need to pay attention to is that the data returned by wechat server does not specify the data encoding type, which leads to garbled codes when it is read directly. We can specify the response encoding for transcoding. We recommend this post www.v2ex.com/t/172276 for detailed explanation

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)
Copy the code

PS:set_cookie is because I did not inherit the fan model from Djangos user model and could not use its own auth module. In the later stage of submitting forms and uploading pictures, I needed to know who uploaded them, so I used the way of recording user ID to cookie

About the cache

The Redis approach is used here. First, Django settings.py introduces the cache configuration

CACHES = {
    'default': {
        'BACKEND': 'django_redis.cache.RedisCache'.# Local file cache
        'LOCATION': '127.0.0.1:6379'.'TIMEOUT': 600.'OPTIONS': {
            "CLIENT_CLASS": "django_redis.client.DefaultClient"."IGNORE_EXCEPTIONS": True,}}}Copy the code

We can then do some basic operations by introducing the Cache module from Django.core. cache import, as shown below

# set the web_access_token key value
The validity period is 110*60s, i.e. 110min
cache.set('web_access_token',web_access_token,110*60)
Copy the code

The official documentation

os.environ.get(”)

You can configure the env file separately for some secret tokens and app_id

Virtualenv is supported by default