def wx_auth(request): code = request.GET.get("code", None) if code is None: return HttpResponse('No Code Provided.') wx_login = WeixinLogin(conf.APP_ID, conf.APP_SECRET) data = wx_login.access_token(code) openid = data.openid scope = data.scope token = data.access_token # 网页授权access_token和公众号的access_token不一样 # 关于网页授权access_token和普通access_token的区别 # 1、微信网页授权是通过OAuth2.0机制实现的,在用户授权给公众号后,公众号可以获取到一个网页授权特有的接口调用凭证(网页授权access_token),通过网页授权access_token可以进行授权后接口调用,如获取用户基本信息; # 2、其他微信接口,需要通过基础支持中的“获取access_token”接口来获取到的普通access_token调用。 wx_user, created = WxUser.objects.get_or_create(openid=openid) if created or wx_user.need_update(): # continue to get userinfo userinfo = wx_login.user_info(token, openid) wx_user = WxUser.objects.filter(openid=openid).first() or WxUser() # update user info wx_user.openid = openid nickname = userinfo.nickname nickname = ''.join(c for c in unicodedata.normalize('NFC', nickname) if c <= '\uFFFF') # remove emoji wx_user.nickname = nickname wx_user.headimg_url = userinfo.headimgurl wx_user.sex = userinfo.sex wx_user.province = userinfo.province wx_user.city = userinfo.city wx_user.country = userinfo.country wx_user.unionid = userinfo.get('unionid', '') wx_user.privilege = json.dumps(userinfo.privilege) wx_user.language = userinfo.language wx_user.save() # 关于UnionID机制 # 1、请注意,网页授权获取用户基本信息也遵循UnionID机制。即如果开发者有在多个公众号,或在公众号、移动应用之间统一用户帐号的需求,需要前往微信开放平台(open.weixin.qq.com)绑定公众号后,才可利用UnionID机制来满足上述需求。 # 2、UnionID机制的作用说明:如果开发者拥有多个移动应用、网站应用和公众帐号,可通过获取用户基本信息中的unionid来区分用户的唯一性,因为同一用户,对同一个微信开放平台下的不同应用(移动应用、网站应用和公众帐号),unionid是相同的。 user = wx_user.auth_user if not user: user = AuthUser.objects.filter(username=wx_user.openid).first() if not user: user = AuthUser.objects.create_user(username=wx_user.openid, password=wx_user.openid) wx_user.auth_user = user wx_user.save() user.backend = 'django.contrib.auth.backends.ModelBackend' login(request, user) request.session['wx_openid'] = openid state = request.GET.get('state', None) if state: url = urlunquote(state) else: url = reverse('weixin:index') return HttpResponseRedirect(url)
def wx_auth(request, app_name): try: app = WxApp.objects.get(name=app_name) request.session['wx_app_name'] = app.name request.session['wx_app_id'] = app.app_id except ObjectDoesNotExist: raise Http404 code = request.GET.get("code", None) if code is None: return HttpResponse('No Code Provided.') wx_login = WeixinLogin(app.app_id, app.app_secret) data = wx_login.access_token(code) openid = data.openid request.session['wx_openid'] = openid scope = data.scope token = data.access_token # 网页授权access_token和公众号的access_token不一样 # 关于网页授权access_token和普通access_token的区别 # 1、微信网页授权是通过OAuth2.0机制实现的,在用户授权给公众号后,公众号可以获取到一个网页授权特有的接口调用凭证(网页授权access_token),通过网页授权access_token可以进行授权后接口调用,如获取用户基本信息; # 2、其他微信接口,需要通过基础支持中的“获取access_token”接口来获取到的普通access_token调用。 if (scope == conf.SCOPE_USERINFO): # continue to get userinfo userinfo = wx_login.user_info(token, openid) wx_user = WxUser.objects.filter(openid=openid).first() or WxUser() # update user info wx_user.openid = openid wx_user.nickname = userinfo.nickname wx_user.headimg_url = userinfo.headimgurl wx_user.sex = userinfo.sex wx_user.province = userinfo.province wx_user.city = userinfo.city wx_user.country = userinfo.country wx_user.unionid = userinfo.get('unionid', None) wx_user.privilege = json.dumps(userinfo.privilege) wx_user.language = userinfo.language # 关于UnionID机制 # 1、请注意,网页授权获取用户基本信息也遵循UnionID机制。即如果开发者有在多个公众号,或在公众号、移动应用之间统一用户帐号的需求,需要前往微信开放平台(open.weixin.qq.com)绑定公众号后,才可利用UnionID机制来满足上述需求。 # 2、UnionID机制的作用说明:如果开发者拥有多个移动应用、网站应用和公众帐号,可通过获取用户基本信息中的unionid来区分用户的唯一性,因为同一用户,对同一个微信开放平台下的不同应用(移动应用、网站应用和公众帐号),unionid是相同的。 if not wx_user.auth_user: user, created = AuthUser.objects.get_or_create( type=AuthUser.WEIXIN, mobile=wx_user.openid) if created or getattr(user, 'customer', None): customer = Customer(name=wx_user.nickname) customer.auth_user = user wx_user.auth_user = user wx_user.save() user.backend = 'django.contrib.auth.backends.ModelBackend' login(request, user) state = request.GET.get('state', None) # next url if state: url = urlunquote(state) else: url = reverse('weixin:index', args=[app_name]) return HttpResponseRedirect(url)
def weixin_callback(self): """回调, 通过code, 获取用户信息""" try: args = request.args.to_dict() code = args.get('code') state = args.get('url') # state = state.replace('$', '#').replace('~', '?').replace('+', '=') wxlogin = WeixinLogin(APP_ID, APP_SECRET_KEY) data = wxlogin.access_token(code) # 这是本人的openid openid = data.openid access_token = data.access_token user = self.suser.get_user_by_openid(openid) # 是否关注 todo wx_subscribe = self.get_wx_response( get_subscribe.format(access_token, openid), "get subscribe") generic_log(wx_subscribe) # if "subscribe" not in wx_subscribe: # logger.error("get subscribe error %s", wx_subscribe) # raise WeixinError(u'get subscribe error') # wx_subscribe = dict() subscribe = wx_subscribe.get("subscribe", 0) data = wxlogin.user_info(data.access_token, data.openid) head = self.get_local_head(data.get('headimgurl'), openid) if not user: # 新用户 # 这是上级openid, 而非本人openid, 根据openid获取上级身份 upper_list = re.findall(r'openid=(.*?)&?', state) upper = upper_list[0] if upper_list else None upperd = self.suser.get_user_by_openid(upper) if upperd: # todo 记录邀请成功时间(如果活动进行中的话 upperd_id = upperd.USid else: upperd_id = None # 添加用户 usid = str(uuid.uuid1()) self.suser.add_model( "User", **{ "USid": usid, "openid": openid, "USlastlogin": datetime.datetime.now().strftime(format_for_db), "USheader": head, "USlevel": 0, "USgender": data.get('sex'), "USname": data.get('nickname'), "UPPerd": upperd_id, "unionid": data.get('openid'), "subscribe": subscribe, }) else: # 老用户 usid = user.USid print(usid) update_dict = { "USlastlogin": datetime.datetime.now().strftime(format_for_db), "USheader": head, "USgender": data.get("sex"), "USname": data.get("nickname"), "unionid": data.get("unionid"), "subscribe": subscribe, } update_result = self.suser.update_user(usid, update_dict) if not update_result: raise SYSTEM_ERROR() # 生成token token = usid_to_token(usid) userlogintime = self.suser.get_user_login_time(usid) now = datetime.datetime.now().strftime(format_for_db) is_today_first = True if userlogintime: is_today_first = bool( userlogintime.USTcreatetime[:-6] < now[:-6]) self.suser.add_model( "UserLoginTime", **{ "ULTid": str(uuid.uuid1()), "USid": usid, "USTip": request.remote_addr, "USTcreatetime": now, }) params_data = { "is_first": int(bool(user)), "subscribe": subscribe, "newtoken": token, "openid": openid, "access_token": access_token, "wximg": wximg, 'user_level': 0 if bool(user) else user.USlevel, "is_today_first": int(is_today_first), "token": usid_to_token(usid), "icon": icon } # params_str = urllib.urlencode(params_data, doseq=True) # redirect_url = state + "?"+params_str # logger.debug("get loggin redirect_url %s", redirect_url) # return redirect(redirect_url) return params_data except WeixinError as e: generic_log(e) return SYSTEM_ERROR(u'code error')