2016-02-26 74 views
4

我使用OAuth2和django-oauth-toolkit django-rest-framework。OAuth2:使用电子邮件而不是用户名进行身份验证

我通常验证自己的用户通过以下方式,以获得令牌:

curl -X POST -d "grant_type=password&username=new_user&password=new_user" -u "GZwzDjPM89BceT8a6ypKGMbXnE4jWSzsyqbM3dlK:" http://localhost:8000/o/token/ 

是否有使用电子邮件,而不是我的用户进行身份验证的用户名的方式?

谢谢!

回答

1

是的!可以在用户模型中将电子邮件设置为username

class User(AbstractBaseUser, PermissionsMixin): 
email = models.EmailField(
    verbose_name='email address', 
    max_length=255, 
    unique=True, 
) 
first_name = models.CharField(max_length=30) 
last_name = models.CharField(max_length=30) 

USERNAME_FIELD = 'email' 

然后电子邮件现在可以在请求中用作username

curl -X POST -d "grant_type=password&[email protected]&password=new_user" -u "GZwzDjPM89BceT8a6ypKGMbXnE4jWSzsyqbM3dlK:" http://localhost:8000/o/token/ 
+1

django中的新增功能1.11。有点晚了,但很高兴知道,谢谢! – Michael

1

我不知道为什么这个问题一直没有回答,但不管怎么说,我希望这将是有益的。我给谁遇到这样的问题太答案:

丑陋但快速的方法:

在您的POST请求中将电子邮件作为用户名发送,然后找到它的真实用户名,并用此数据替换POST请求;这在所有的中间件:

class DisableCSRF(object): 
    """Middleware for disabling CSRF in a specified app name. 
    """ 

    def process_request(self, request): 
     """Preprocess the request. 
     """ 

     if (resolve(request.path_info).app_name == "api") or (
       resolve(request.path_info).namespace == "oauth2_provider"): 

      if resolve(request.path_info).namespace == "oauth2_provider": 

       post_data = request.POST.copy() 

       true_username = User.objects.get(
        email=request.POST.get("username") 
       ).username 
       post_data["username"] = true_username 
       request.POST = post_data 

      setattr(request, '_dont_enforce_csrf_checks', True) 
     else: 
      pass # check CSRF token validation 

优雅和良好的实践方式:

创建自己的类来请求身份验证令牌,以便您可以收到电子邮件作为用户名。您甚至可以添加更多自定义身份验证,如Facebook或Google登录。这绝对是最好的方法,但需要更多的时间来开发,所以如果你有足够的时间来实现它,那就取决于你。

希望回答这个问题还不算太晚。

2

如果你不想(或不能)创建自定义的用户模型,这里有一个简单的解决办法:只要覆盖rest_framework_social_oauth2.views.TokenView这样的:

from django.contrib.auth import get_user_model 
import rest_framework_social_oauth2.views 

class TokenView(rest_framework_social_oauth2.views.TokenView): 
    def create_token_response(self, request): 
     email = request.POST.pop('email', None) 
     if email: 
      username = get_user_model().objects.filter(email=email[0]).values_list('username', flat=True).last() 
      request.POST['username'] = username 
     return super(TokenView, self).create_token_response(request) 

然后,在你urls.conf将此自定义视图连接到oauth/token图案,例如:

urlpatterns = [ 
    url(r'^oauth/token', my_auth.TokenView.as_view()), # The customized TokenView 
    url(r'^oauth/', include('rest_framework_social_oauth2.urls')), # Original URLs 
] 
相关问题