opened
garyhurtz
username_0
I am using wechatpy to add wechat login capability to a website, and I found that WeChat's servers refuse to accept the URLs generated by WeChatOAuth.qrconnect_url.

After some investigation, I found that this method does not encode URLs correctly.

WeChat servers will accept the URLs after changing:

        redirect_uri = quote(self.redirect_uri)

to

        redirect_uri = quote(self.redirect_uri, safe=u'')

Wanted to pass this along to the team and other users who are unable to present their users with the login QR code.
-gary
qrconnect_url encoding issues
issue
created
messense
username_1
Would you like to open a PR to fix it?

发自我的 iPhone
comment
closed
messense
username_1
issue
created
Brightcells
username_2
Why not use quote_plus instead of quote
comment
created
rockallite
username_3
@username_1 For Python 2.7, commit https://github.com/jxtech/wechatpy/commit/3610e8112fbee2d224c11b961ec73ea3ce65e0af introduce a new problem: cache pollution in `quote()`. It causes `UnicodeDecodeError` in subsequent calls to `quote()` with a non-ascii value, if any function in wechatpy which involves in calling `quote(..., safe='')` (the `safe` parameter is a unicode) gets called first in a Python process.

I can confirm that this bug still exists in wechatpy 1.7.4.

For example, after starting a Django dev server, first make an OAuth request in WeChat devtools, then make a fuzzy search with non-ascii characters in Django admin. A typical traceback would look like this:

```
  ...
  File "/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib.py", line 1297, in quote
    if not s.rstrip(safe):
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)
```

The corresponding interactive traceback view in Django would look like this:

```
...
/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib.py in quote
1290.         (quoter, safe) = _safe_quoters[cachekey]
1291.     except KeyError:
1292.         safe_map = _safe_map.copy()
1293.         safe_map.update([(c, c) for c in safe])
1294.         quoter = safe_map.__getitem__
1295.         safe = always_safe + safe
1296.         _safe_quoters[cachekey] = (quoter, safe)
1297.     if not s.rstrip(safe): ...
1298.         return s
1299.     return ''.join(map(quoter, s))
1300.
1301. def quote_plus(s, safe=''):
1302.     """Quote the query fragment of a URL; replacing ' ' with '+'"""
1303.     if ' ' in s:

Local vars
Variable | Value
      -- | --
cachekey | ('', 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.-')
  quoter | <built-in method __getitem__ of dict object at 0x10e5b4d70>
       s | '\xe4\xb8\xad'
    safe | u'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.-'
```

As you can see, the `safe` variable from `_safe_quoters` dict (as a cache) becomes a unicode string, which ought to be a byte string.

If you make the fuzzy search in Django admin first, everything is fine.

The proper fix in wechatpy should be calling `quote` with byte strings, like this: `quote(self.redirect_url, safe=b'')` (because of the `from __future__ import unicode_literals` statement at the top of a file).

A temporary fix in an existing (Python 2.7) project would be calling the following code in a bootstrap script, so the `quote()` cache is filled with a proper value:

```
from urllib import quote


quote('non-empty-string', safe='')
```

A good place for a Django project would be `<project_name>/__init__.py`.
comment
reopened
messense
username_1
I am using wechatpy to add wechat login capability to a website, and I found that WeChat's servers refuse to accept the URLs generated by WeChatOAuth.qrconnect_url.

After some investigation, I found that this method does not encode URLs correctly.

WeChat servers will accept the URLs after changing:

        redirect_uri = quote(self.redirect_uri)

to

        redirect_uri = quote(self.redirect_uri, safe=u'')

Wanted to pass this along to the team and other users who are unable to present their users with the login QR code.
-gary
qrconnect_url encoding issues
issue