用django-social-auth 做中國社交網站三方登入(qq,微博,豆瓣,百度,人人,微信支援)
TODO
我寫這個demo之後, python-social-auth, django-social-auth的作者(一個人),
對這兩個庫進行了比較大的更新,pip裡面甚至下掉了django-social-auth, 0.8.1這個版本,
因此讓demo能夠跑起來,你可能需要用我的兩個fork版本.
python-social_auth一個我的fork版本
django-social-auth一個我的fork版本
我已經在requirements.txt中去掉了這兩個關鍵庫,請手動clone安裝.
注意安裝順序,需要先裝python-social-auth, 再裝django-social-auth(因為裡面的一些依賴我暫時沒改)
git clone https://github.com/duoduo369/python-social-auth.git
git clone https://github.com/duoduo369/django-social-auth.git
cd python-social-auth的目錄
pip install -e .
cd django-social-auth的目錄
pip install -e .
由於這兩個版本還在不定期更新中,因此這個demo過一段時間我會做一次更新,把詳細的使用步驟在寫進去。
fork版本中提供了裡面原來不支援的一些三方backend,現在中國常用的幾個backend基本都有了: 微信,微博,qq,人人,豆瓣,百度
Begin
需求專案用的django版本為1.4.8, 使用者系統採用django預設系統,而且已經有幾萬使用者,改動django的使用者model或者表,django部分做三方登入在awesome-django中推薦的也是django-social-auth,這兩天試用了一下,寫個demo。
程式碼地址 裡面只添加了必要的requirements,程式碼中配置的各個app key都是一個試用的app(沒有過稽核),不用費心思搞我了...
social_auth使用方式
每個網站都需要註冊app,這個就不說了
這裡以一個heroku的app為例: http://llovebaimuda.herokuapp.com/
注意social_auth的配置方式不能配置回撥地址,因此必須在各大網站將回調地址設定為/你的域名/complete/weibo
,
這裡就是http://llovebaimuda.herokuapp.com/complete/weibo/
,當然不同的網站略有不同。
除錯注意! 本地設定hosts
windows %systemroot%\system32\drivers\etc\hosts
需要在開始選單找到notepad.exe,右鍵以管理員身份執行,在開啟這個檔案修改
linux `sudo vi /etc/hosts
將llovebaimuda.herokuapp.com改為本地或者虛擬機器的ip, 開發就靠他了。
192.168.9.191 llovebaimuda.herokuapp.com
各個網站配置
新浪
http://open.weibo.com/webmaster
,下進入你的app
左側網站資訊
基本資訊可以看到域名,app key, app secret
左側介面管理 授權機制
找到OAuth2.0 授權設定 授權回撥頁
設定為http://llovebaimuda.herokuapp.com/complete/weibo/
http://connect.qq.com/manage/index
,進入你申請開發的app
左側頭像的地方就可以看到 app id, app key
點選資訊編輯,找到回撥地址
,qq回撥只要填寫域名即可(沒有http)llovebaimuda.herokuapp.com
豆瓣
http://developers.douban.com/apikey/
, 進入你申請開發的app
概覽部分可以看到api key和secrect
豆瓣不需要填寫回調地址,不過需要新增測試使用者,在左側測試使用者
部分新增使用者的豆瓣id
social_auth的一些配置
settings
pipeline
SOCIAL_AUTH_PIPELINE = (
'social.pipeline.social_auth.social_details',
'social.pipeline.social_auth.social_uid',
'social.pipeline.social_auth.auth_allowed',
'social_auth.backends.pipeline.social.social_auth_user',
# 使用者名稱與郵箱關聯,文件說可能出現問題
# 'social_auth.backends.pipeline.associate.associate_by_email',
'social_auth.backends.pipeline.misc.save_status_to_session',
'social_auth.backends.pipeline.user.create_user',
'social_auth.backends.pipeline.social.associate_user',
'social_auth.backends.pipeline.social.load_extra_data',
'social_auth.backends.pipeline.user.update_user_details',
'social_auth.backends.pipeline.misc.save_status_to_session',
)
你想用哪幾種oauth
AUTHENTICATION_BACKENDS = (
'social_auth.backends.contrib.douban.Douban2Backend',
# 注意這個比較特殊,因為django-social-auth是依賴python-social-auth的
# python-social-auth==0.1.26,已經包含的qq的backend
# django-social-auth==0.8.1, 還沒包含進來
# 你需要在django-social-auth/social_auth/backends/contrib中新增一個檔案qq.py
# 就一行
# from social.backends.qq import QQOAuth2 as QQBackend
# 然後setup一下就ok
'social_auth.backends.contrib.qq.QQBackend',
'social_auth.backends.contrib.weibo.WeiboBackend',
# 必須加,否則django預設使用者登入不上
'django.contrib.auth.backends.ModelBackend',
)
模板的一些配置
TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.auth.context_processors.auth',
# login 在template中可以用 "{% url socialauth_begin 'douban-oauth2' %}"
'social_auth.context_processors.social_auth_by_type_backends',
'social_auth.context_processors.social_auth_login_redirect',
)
各種重定向連線
SOCIAL_AUTH_LOGIN_URL = '/login-url/'
SOCIAL_AUTH_LOGIN_ERROR_URL = '/login-error/'
SOCIAL_AUTH_LOGIN_REDIRECT_URL = '/logged-in/'
SOCIAL_AUTH_NEW_USER_REDIRECT_URL = '/new-users-redirect-url/'
SOCIAL_AUTH_NEW_ASSOCIATION_REDIRECT_URL = '/new-association-redirect-url/'
各種key, secret
SOCIAL_AUTH_WEIBO_KEY = 'YOUR KEY'
SOCIAL_AUTH_WEIBO_SECRET = 'YOUR SECRET'
SOCIAL_AUTH_QQ_KEY = 'YOUR KEY'
SOCIAL_AUTH_QQ_SECRET = 'YOUR SECRET'
SOCIAL_AUTH_DOUBAN_OAUTH2_KEY = 'YOUR KEY'
SOCIAL_AUTH_DOUBAN_OAUTH2_SECRET = 'YOUR SECRET'
urls
urlpatterns = patterns('',
...
url(r'', include('social_auth.urls')),
...
)
template
注意實現一下/logout的方法,用django自帶的即可
登入
<li><a rel="nofollow" href="{% url socialauth_begin 'weibo' %}">weibo</a></li>
<li><a rel="nofollow" href="{% url socialauth_begin 'qq' %}">qq</a></li>
<li><a rel="nofollow" href="{% url socialauth_begin 'douban-oauth2' %}">douban</a></li>
登出
<a href="/logout" > 登出 </a>
試用
此時User表沒有任何使用者,登入方式有weibo,douban,qq
In [0]: User.objects.all()
Out[0]: []
In [1]: UserSocialAuth.objects.all()
Out[1]: []
開啟http://llovebaimuda.herokuapp.com/
,別忘了改host
注意註釋或者不註釋此句的區別 'social_auth.backends.pipeline.associate.associate_by_email',
先看不註釋,我weibo,qq,douban的郵箱都是一個郵箱
註釋掉associate_by_email
初始狀態
In [0]: User.objects.all()
Out[0]: []
In [1]: UserSocialAuth.objects.all()
Out[1]: []
用weibo登入, 頁面重定向到http://llovebaimuda.herokuapp.com/new-users-redirect-url/
In [2]: User.objects.all()
Out[2]: [<User: 咄咄369>]
In [3]: UserSocialAuth.objects.all()
Out[3]: [<UserSocialAuth: UserSocialAuth object>]
點選登出,在用qq登入,重定向到http://llovebaimuda.herokuapp.com/new-association-redirect-url/
In [4]: User.objects.all()
Out[4]: [<User: 咄咄369>]
In [5]: UserSocialAuth.objects.all()
Out[5]: [<UserSocialAuth: UserSocialAuth object>, <UserSocialAuth: UserSocialAuth object>]
點選登出,在用douban登入,重定向到http://llovebaimuda.herokuapp.com/new-association-redirect-url/
In [6]: User.objects.all()
Out[6]: [<User: 咄咄369>]
In [7]: UserSocialAuth.objects.all()
Out[7]: [<UserSocialAuth: UserSocialAuth object>, <UserSocialAuth: UserSocialAuth object>]
在不登出的情況下點選任何一種登入都會跳轉到http://llovebaimuda.herokuapp.com/new-association-redirect-url/
點選登出後,再點選任何一種登入會跳到http://llovebaimuda.herokuapp.com/logged-in/
開啟associate_by_email
初始狀態
In [0]: User.objects.all()
Out[0]: []
In [1]: UserSocialAuth.objects.all()
Out[1]: []
用weibo登入, 頁面重定向到http://llovebaimuda.herokuapp.com/new-users-redirect-url/
In [2]: User.objects.all()
Out[2]: [<User: 咄咄369>]
In [3]: UserSocialAuth.objects.all()
Out[3]: [<UserSocialAuth: UserSocialAuth object>]
點選登出,在用qq登入,重定向到`http://llovebaimuda.herokuapp.com/new-users-redirect-url/'
In [4]: User.objects.all()
Out[4]: [<User: 咄咄349>, <User: 咄咄>]
In [5]: UserSocialAuth.objects.all()
Out[5]: [<UserSocialAuth: UserSocialAuth object>, <UserSocialAuth: UserSocialAuth object>]
點選登出,在用douban登入,重定向到`http://llovebaimuda.herokuapp.com/new-users-redirect-url/'
In [4]: User.objects.all()
Out[4]: [<User: 咄咄349>, <User: 咄咄>, <User: 43901973>]
In [5]: UserSocialAuth.objects.all()
Out[5]: [<UserSocialAuth: UserSocialAuth object>, <UserSocialAuth: UserSocialAuth object>, <UserSocialAuth: UserSocialAuth object>]
點選登出, 用任何一種方式登入(以qq為例), 頁面跳轉到http://llovebaimuda.herokuapp.com/logged-in/
在登出的情況下使用任一一種與4不同的登入方式登入,會出現異常(以豆瓣為例)
AuthAlreadyAssociated at /complete/douban-oauth2/
This douban-oauth2 account is already in use.
各種重定向的思考
SOCIAL_AUTH_LOGIN_URL = '/login-url/'
, 暫時沒發現什麼用
SOCIAL_AUTH_LOGIN_ERROR_URL = '/login-error/'
, 登入異常,應該引導使用者重新去登入
SOCIAL_AUTH_LOGIN_REDIRECT_URL = '/logged-in/'
, 成功登入頁面
SOCIAL_AUTH_NEW_USER_REDIRECT_URL = '/new-users-redirect-url/'
, django部分新建使用者,在這個頁面可以引導使用者設定郵箱之類的附加資訊
SOCIAL_AUTH_NEW_ASSOCIATION_REDIRECT_URL = '/new-association-redirect-url/'
, django使用者新建了一個關聯的三方賬戶,此連結沒想出有什麼特殊需求,可以直接引導到登入成功頁面