Django Python Social Auth 只允许特定用户登录

3
我希望仅允许从@companyname.net电子邮件或列表中的电子邮件地址的用户,通过Python Social Auth通过google+登录。 我应该如何完成这项操作?
SOCIAL_AUTH_GOOGLE_OAUTH2_WHITELISTED_DOMAINS = ['companyname.net']

这是我当前在settings.py中的设置,但这只允许@companyname.net的员工登录。


你所拥有的列表是基于域名的吗?我的意思是,你会允许从特定域名发送的所有电子邮件,还是只限于特定的电子邮件地址? - Tales Pádua
我想允许所有@companyname.net的人,并且只允许来自其他域的特定人员。 - Jainil Shah
3个回答

3

解决这个问题的一种方法是覆盖 Python-Social-Auth 管道。

您可以使用以下内容覆盖 create_user:

def create_user(strategy, details, user=None, *args, **kwargs):
    if user:
        return {'is_new': False}

    allowed_emails = get_list_of_emails()

    fields = dict((name, kwargs.get(name, details.get(name)))
                  for name in strategy.setting('USER_FIELDS', USER_FIELDS))
    if not fields:
        return

    if fields[email] in allowed_emails:        
        return {
            'is_new': True,
            'user': strategy.create_user(**fields)
        }

    return

这个方法 get_list_of_emails() 的作用是从文件或数据库中加载电子邮件。它需要返回一个电子邮件列表。

然后,在您的设置中的 SOCIAL_AUTH_PIPELINE 中,您需要将 create_user 替换为您自定义的方法:

SOCIAL_AUTH_PIPELINE = (
    'social.pipeline.social_auth.social_details',
    'social.pipeline.social_auth.social_uid',
    'social.pipeline.social_auth.auth_allowed',
    'social.pipeline.social_auth.social_user',
    'social.pipeline.user.get_username',
    'path.to.my.method.create_user',
    'social.pipeline.social_auth.associate_user',
    'social.pipeline.social_auth.load_extra_data',
    'social.pipeline.user.user_details',
)

这样,您可以保持白名单,并将想要的电子邮件存储在可以使用get_list_of_emails()方法加载的某个地方。
更多信息请参见文档

我没有测试过,但应该可以工作。调试以查看电子邮件是否真的是字段的关键。 - Tales Pádua
如果用户的电子邮件不在allowed_emails中,我该如何将用户返回到特定页面? - Jainil Shah
只需在settings.py文件中设置SOCIAL_AUTH_LOGIN_ERROR_URL为您希望用户重定向的URL即可。 - Tales Pádua

0

将注册限制为某些电子邮件或域称为白名单

正如文档所解释的那样,您有两种可能的白名单方式,即通过提供

  • 要列入白名单的域列表,SOCIAL_AUTH_<BACKEND_NAME>_WHITELISTED_DOMAINS = ['foo.com', 'bar.com']

  • 要列入白名单的电子邮件地址列表,SOCIAL_AUTH_<BACKEND_NAME>_WHITELISTED_EMAILS = ['me@foo.com', 'you@bar.com']

由于OP希望

允许@companyname.net的所有人以及来自其他域的一些特定人员。

那么 OP 可以继续使用 SOCIAL_AUTH_<BACKEND_NAME>_WHITELISTED_DOMAINS,因为 OP 已经在使用它,并且还可以引入 SOCIAL_AUTH_<BACKEND_NAME>_WHITELISTED_EMAILS 来添加 OP 想要登录的特定电子邮件。


0

这是我经过测试的实现:

import os
import psycopg2
from Utils.common import setup_logging

LOG = setup_logging(__name__)
USER_FIELDS = ['username', 'email']


def get_whitelisted_emails():
    whitelisted_domains_emails = []
    try:
        connection = psycopg2.connect(user=os.environ.get('DB_USER'),
                                      password=os.environ.get('DB_PASSWORD'),
                                      host='localhost',
                                      port=os.environ.get('DB_PORT'),
                                      database=os.environ.get('DB_NAME'))
        cursor = connection.cursor()
        get_whitelisted_domains_emails = "SELECT domain, email FROM cortex_emails WHERE is_active=True;"
        cursor.execute(get_whitelisted_domains_emails)
        whitelisted_domains_emails = cursor.fetchall()
        connection.close()
    except(Exception, psycopg2.Error) as error:
        LOG.info('Failed to connect to database...')

    return [email for _, email in whitelisted_domains_emails]


def create_user(strategy, details, user=None, *args, **kwargs):
    if user:
        return {'is_new': False}

    allowed_emails = get_whitelisted_emails()

    fields = dict((name, kwargs.get(name, details.get(name)))
                  for name in strategy.setting('USER_FIELDS', USER_FIELDS))
    if not fields:
        return

    if fields['email'] in allowed_emails:
        return {
            'is_new': True,
            'user': strategy.create_user(**fields)
        }

    return

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接