1. 程式人生 > >用django-social-auth 做中國社交網站三方登入(qq,微博,豆瓣,百度,人人,微信支援)

用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/

qq

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使用者新建了一個關聯的三方賬戶,此連結沒想出有什麼特殊需求,可以直接引導到登入成功頁面