Django 使用 Allauth 进行身份验证

Posted

技术标签:

【中文标题】Django 使用 Allauth 进行身份验证【英文标题】:Django rest auth with Allauth 【发布时间】:2017-07-16 04:43:46 【问题描述】:

我已经使用 Allauth 实现了 django rest auth,如果我通过 google access_token 登录,它可以正常工作,但是在某些情况下,某些客户端设备需要通过 google id_token 登录。 如果我使用 id_token 而不是 access_token,则会出现错误


  "non_field_errors": [
    "Incorrect value"
  ]

请帮帮我

【问题讨论】:

你能提供更多的上下文吗?请求有效载荷?网址?等 你有想过这个吗? 我遇到了同样的错误。 你是如何从谷歌获得 access_token 的? 你有想过这个吗? 【参考方案1】:

像这样更新你的文件

../allauth/socialaccount/providers/google/provider.py:

class GoogleProvider(OAuth2Provider):
    ....

    def extract_uid(self, data):
        try:
            return str(data['id'])
        except KeyError:
            return str(data['user_id'])

../allauth/socialaccount/providers/google/views.py:

class GoogleOAuth2Adapter(OAuth2Adapter):
    provider_id = GoogleProvider.id
    access_token_url = 'https://accounts.google.com/o/oauth2/token'
    authorize_url = 'https://accounts.google.com/o/oauth2/auth'
    profile_url = 'https://www.googleapis.com/oauth2/v1/userinfo'
    token_url = 'https://www.googleapis.com/oauth2/v1/tokeninfo'

    def complete_login(self, request, app, token, **kwargs):
        if 'rest-auth/google' in request.path:
            print('rest-auth api')
            # /api/rest-auth/google
            # but not for website login with google
            resp = requests.get(self.token_url,
                            params='id_token': token.token,
                                    'alt': 'json')
        else:
            print('else else rest-auth api')
            resp = requests.get(self.profile_url,
                            params='access_token': token.token,
                                    'alt': 'json')
        resp.raise_for_status()
        extra_data = resp.json()
        login = self.get_provider() \
            .sociallogin_from_response(request,
                                   extra_data)
        return login


oauth2_login = OAuth2LoginView.adapter_view(GoogleOAuth2Adapter)
oauth2_callback = OAuth2CallbackView.adapter_view(GoogleOAuth2Adapter)

对于使用 id_token,您只会获得这些文件(access_type、受众、电子邮件、email_verified、expires_in、issued_at、issued_to、issuer、nonce、scope、user_id、verified_email)。因此,如果您的用户表需要 phonename,您可以将 name='' 等设置为空。为此,您可以使用以下代码。

将用户模型必填字段设置为空以覆盖 id_token 案例

这取决于您的用户模型,在我的情况下,我们需要电话和姓名,所以我将它们设置为空。如果你不这样做,你会得到失败的约束错误。

../allauth/socialaccount/providers/base.py

class Provider(object):
    def sociallogin_from_response(self, request, response):
        ....
        common_fields = self.extract_common_fields(response)
        common_fields['name'] = common_fields.get('name', '')
        common_fields['phone'] = common_fields.get('phone', '')
        common_fields['username'] = uid
        ....

我已将用户名设置为从社交平台 api 获取的用户 ID。稍后我会强制用户更新其详细信息(用户名、姓名、电话等)。

【讨论】:

嘿.. 我是 django 的新手。只是掌握事情的窍门。你能告诉我在哪里进行这些更改吗?应该写一个基于allauth的自定义provider吗? 你需要自定义 django-allauth 库本身。

以上是关于Django 使用 Allauth 进行身份验证的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 django-allauth 访问用户名和配置文件

如何使用 django-allauth 访问用户名和配置文件

如何使用 django-allauth 进行自定义注册?

django-allauth 检索头像头像

django-allauth:如何修改电子邮件确认 url?

Django allauth 在不注销的情况下更改密码