欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解從Django Allauth中進行登錄改造小結

 更新時間:2019年12月18日 08:26:47   作者:敖天羽  
這篇文章主要介紹了從 Django Allauth 中進行登錄改造小結,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

大概來介紹一下 Django Allauth 改造的期間遇到的一些問題和改造方法,在此之前我只想說——Django Allauth 是屑。

為什么我說 Django Allauth 是屑

入職之初我就接到了一些第三方登錄的任務,然而 Django Allauth 將內部封裝的太好,暴露的 API 不足,更新又慢,issue 和 PR 很少有人處理,當你需要擴展時,很多情況下你只能用一些 hack 的手段去解決問題,非常蛋疼,所以當時就決定慢慢的切到自己的一套 Auth 體系中。

目前已經做的是第三方登錄的部分,賬號管理的部分還沒有遷移,之前稍微看了一下,要遷移的成本還是比較麻煩的。

遷移成本在哪里

Django 中的賬號密碼登錄一般是由本身提供的 auth 表進行擴展的結果,而 allauth 在此基礎上擴充了第三方登錄的幾個表,再和本身的 auth user 表關聯(lián)。而這一部分是構建在 Allauth 內部的 model 內,且沒有暴露任何的方法來修改結構(當然可能也是因為真的不好改),導致一旦不滿足需求就很難搞,因為數據已經放在那里了,刷數據同步的方案對于大流量網站來說也并不是很友好的選擇。

此外,在路由上,由于我們需要盡可能的無痛遷移和在漸進式切換時的平穩(wěn)降級,因此只能通過簡單粗暴的路由覆蓋操作,這極度依賴路由的解析順序。

數據庫擴展與 provider 變更

說了這么多,其實關鍵點并不在于「問題在哪里」,而在于「我是怎么解決這些問題的」。

Allauth 一個平臺的注冊是一個 provider,比如 「wechat」、「weibo」、「qq」,整張表是一對一的關系,那么問題來了,我們知道,國內的平臺往往并不是一個 appid 和 key 能搞定的事情,對于 web 和移動端的平臺來說,其實是兩個 appid 共享一套 unionid,盡管官方提供了一套增加 Provider 的擴展方式,但實際上是沒有必要的,因為 Web 和移動端來說,獲得用戶信息的接口是共享的,而移動端并不用通過后端獲取 access_token。在綁定上,實際上也是同一個平臺。

因此我們擴充了一張表來解決這個問題,將我們額外的信息放在了額外添加的表中。

之后要解決的就是 admin 的 provider select 問題,它會進行一次校驗,所以我們必須要取消這些校驗并把 select 改成 input。

首先,我們要取消 Model 層的校驗, Proxy 可以對表進行一些覆蓋式的操作(但不能改變表結構):

class CustomSocialApp(SocialApp):
  class Meta:
    proxy = True

  def clean_fields(self, exclude=None):
    # 別校驗了
    pass

  def full_clean(self, exclude=None, validate_unique=True):
    # 別校驗了
    pass

  def clean(self, exclude=None, validate_unique=True):
    # 別校驗了
    pass

這里我們在原來的 SocialApp 的基礎上新建一個屬于自己的新的 Admin,他本質上還是操作 SocialApp 表,只是挪出來方便我們自定義而已:

class CustomSocialAppAdmin(SocialAppAdmin):
  list_display = ('provider_text', 'name')
  form = CustomAppAdminForm

  def get_form(self, request, obj=None, **kwargs):
    kwargs['widgets'] = {'provider': forms.TextInput}
    return super().get_form(request, obj, **kwargs)

  def provider_text(self, obj):
    return obj.provider

但是這樣就會遇到一個 provider 的校驗問題,這也就是上面我們還沒有寫完的 CustomAppAdminForm 的部分,我們將校驗的部分用自定義的 form 完全取消:

class CustomSocialAppAdminForm(forms.ModelForm):
  class Meta:
    model = CustomSocialApp
    fields = '__all__'
    widgets = {'provider': forms.TextInput()}

  def clean(self):
    # 別校驗了
    if self.has_error('provider'):
      del self._errors['provider']
    self.cleaned_data['provider'] = self.data['provider']
    return self.cleaned_data

這樣就完成了校驗的修改,成了一個完全體的 input 覆蓋了原來的 select。

第三方登錄與綁定流程

上面可以任意在表中拓展 provider 了 ,但重頭戲其實是:搞清楚 allauth 原本的登錄和綁定流程,完美的 copy 一份流程,這樣才能實現(xiàn)平穩(wěn)降級和無痛遷移。

查找賬號

  1. 獲取用戶授權信息中的 uid
  2. 在 AllauthSocialAccount 表中獲取到對應的數據,如果沒有則返回 None

登錄流程

  1. 確保用戶是匿名用戶:request.user.is_anouymous 且已經存在對應的賬號
  2. 更新 AllauthSocialAccount 表中的數據到最新
  3. 根據 social account 更新 social token
  4. 寫入 session(Django 中自帶 login 函數)

注冊流程

  1. 確保用戶是匿名用戶且不存在對應賬號
  2. 創(chuàng)建新用戶(要點是生成用戶名和昵稱),在 Django 中有 create_user 可以直接創(chuàng)建
  3. 寫入 AllatuhSocialAccount 和 AllauthSocialToken
  4. 寫入 session 登錄

綁定流程

  • 用戶不是匿名用戶
  • 查找對應的第三方賬號是否已經被綁定
  • 更新 AllauthSocialAccount 表
  • 更新 social token

只要按照這個流程實現(xiàn)下來就可以了,而同一平臺多 provider(appid)的差異功能與核心部分無關,可以在各社交媒體對應的文件中單獨實現(xiàn)。

構建新的賬號系統(tǒng)

現(xiàn)在我們徹底將第三方登錄抽離了出來,接下來需要抽出賬號的部分,賬號登錄和注冊本質上還是 Django 提供的那些東西,因此比較好抽,需要兼容的部分主要在于「忘記密碼」和「重置密碼」。

我們來思考一下為什么這部分需要做兼容:

一般來說我們都是在重置密碼時在手機或者郵箱里收到一個驗證郵件,里面會附上一個隨機字符串用來保證連接的唯一性。而在我們替換過程中,我們不能讓一群用戶已經發(fā)送過但還沒有使用的隨機字符串不可用,從可讀的角度來看,生成的內容也應該和原來差不多(同時也是避免沖突),因此需要抄一下它的忘記密碼。

在 account/forms 中表明了 token 的生成算法:

from django.contrib.auth.tokens import PasswordResetTokenGenerator
token_generator = PasswordResetTokenGenerator()
# 生成 token
key = token_generator.make_token(user)
# 檢查 token
token_generator.check_token(user, key)

Allauth 中將 user 用 base36 加密了,兼容 Python2,所以 utils 中的語句略長,由于我們直接是 Python3,所以只剩下這些句子:

from django.utils.http import base36_to_int
from django.utils.http import int_to_base36


def user_pk_to_url_str(user):
  return int_to_base36(user.pk)


def url_str_to_user_pk(s):
  return base36_to_int(s)

所有內容將會被存儲在 account_emailconfirmation 表中,這樣就能保證對應的關系了。

總結

在賬號的部分由于還沒有改完,所以可以說的不多,只是做了一些微小的工作,對于這種可能需要根據國情定制的需求,建議大家還是小心使用。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • Python txt文件加入字典并查詢的方法

    Python txt文件加入字典并查詢的方法

    今天小編就為大家分享一篇Python txt文件加入字典并查詢的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-01-01
  • python中的annotate函數使用

    python中的annotate函數使用

    這篇文章主要介紹了python中的annotate函數使用方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • matplotlib繪制兩點間連線的幾種方法實現(xiàn)

    matplotlib繪制兩點間連線的幾種方法實現(xiàn)

    本文主要介紹了matplotlib繪制兩點間連線的幾種方法實現(xiàn),主要介紹了4種方法,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Python機器學習應用之基于線性判別模型的分類篇詳解

    Python機器學習應用之基于線性判別模型的分類篇詳解

    線性判別分析(Linear?Discriminant?Analysis,?LDA)是一種監(jiān)督學習的降維方法,也就是說數據集的每個樣本是有類別輸出。和之前介紹的機器學習降維之主成分分析(PCA)方法不同,PCA是不考慮樣本類別輸出的無監(jiān)督學習方法
    2022-01-01
  • Python中第三方庫Faker的使用詳解

    Python中第三方庫Faker的使用詳解

    在如今的大數據時代,數據的價值可想而知。有時候為了做測試,需要模擬真實的環(huán)境,但是又不能直接使用真實數據,就需要我們認為制造一些數據出來。這時候就要來說說Python這的Faker庫了,快跟隨小編來學習一下這個庫吧
    2022-04-04
  • Python之is與==的區(qū)別詳解

    Python之is與==的區(qū)別詳解

    這篇文章主要介紹了Python之is與==的區(qū)別詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下
    2021-09-09
  • Pycharm中如何關掉python console

    Pycharm中如何關掉python console

    這篇文章主要介紹了Pycharm中如何關掉python console,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-10-10
  • python使用smtplib模塊發(fā)送郵件

    python使用smtplib模塊發(fā)送郵件

    這篇文章主要為大家詳細介紹了python使用smtplib模塊發(fā)送郵件,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • Python使用django解決跨域請求的問題

    Python使用django解決跨域請求的問題

    這篇文章主要給大家介紹了python如何使用django解決跨域請求的問題,文中有詳細的代碼示例,具有一定的參考價值,需要的朋友可以參考下
    2023-07-07
  • python 反向輸出字符串的方法

    python 反向輸出字符串的方法

    今天小編就為大家分享一篇python 反向輸出字符串的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-07-07

最新評論