Django自定义后端:使用自定义后端进行身份验证时无法登录

时间:2016-01-13 18:41:59

标签: django django-authentication

我的主要要求是进行电子邮件身份验证。虽然我的自定义身份验证后端似乎工作正常,但即使在使用我的自定义后端成功进行身份验证后,package com.spark.play; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import org.apache.spark.SparkConf; import org.apache.spark.SparkContext; import org.apache.spark.api.java.JavaRDD; import org.apache.spark.api.java.function.Function; import org.apache.spark.sql.DataFrame; import org.apache.spark.sql.SQLContext; import org.apache.spark.streaming.Durations; import org.apache.spark.streaming.StreamingContext; import org.apache.spark.streaming.api.java.JavaDStream; import org.apache.spark.streaming.api.java.JavaPairDStream; import org.apache.spark.streaming.api.java.JavaPairInputDStream; import org.apache.spark.streaming.api.java.JavaStreamingContext; import org.apache.spark.streaming.kafka.KafkaUtils; import kafka.serializer.StringDecoder; import scala.Tuple2; public class SparkUserStreaming { public static void main(String args[]){ System.out.println("Start User streaming App for Policy..."); SparkConf sparkConf = new SparkConf().setAppName("Policy").setMaster("local[2]").setJars( JavaStreamingContext.jarOfClass(SparkUserStreaming.class)).setSparkHome("SPARK_HOME"); SparkContext sc = new SparkContext(sparkConf); StreamingContext streamContex = new StreamingContext(sc, Durations.seconds(60)); JavaStreamingContext jssc = new JavaStreamingContext(streamContex); Map<String, Integer> topicMap = new HashMap<String, Integer>(); topicMap.put("user", 1); String brokers = "vchenst:9092"; String topics = "user"; HashSet<String> topicsSet = new HashSet<>( Arrays.asList(topics.split(","))); HashMap<String, String> kafkaParams = new HashMap<>(); kafkaParams.put("metadata.broker.list", brokers); JavaPairInputDStream<String, String> dstream = KafkaUtils.createDirectStream( jssc, String.class, String.class, StringDecoder.class, StringDecoder.class, kafkaParams, topicsSet ); JavaPairDStream<String, String> mesages = dstream.window(Durations.seconds(300), Durations.seconds(60)); JavaDStream<User> streamData = mesages.map(new Function<Tuple2<String, String>, User>() { public User call(Tuple2<String, String> tuple2) throws Exception { User user = new User(); //System.out.println("Line ::" + tuple2._1()); String[] dataArray = tuple2._2().split(","); //user:arul,product:mobile,country:india,state:tn,price:1000,txid:12300086,datetime:2009-01-16 16:47:08 user.setName(dataArray[0]); user.setProduct(dataArray[1]); user.setCountry(dataArray[2]); user.setState(dataArray[3]); user.setPrice(Double.parseDouble(dataArray[4])); user.setTxId(dataArray[5]); user.setDateTime(dataArray[6]); return user; } }); final SQLContext sqlContext = new SQLContext(sc); streamData.foreachRDD(new Function<JavaRDD<User>, Void>() { public Void call(JavaRDD<User> rdd) { DataFrame userDf = sqlContext.createDataFrame(rdd, User.class); //userDf.show(); //Rules applied for Five Minutes //Rule 1 - Print Users making more than 2 transactions userDf.groupBy("txId").count() .withColumnRenamed("count", "n") .filter("n >= 2") .show(); //Rule 2 - Print User making tx with cost of more than 1000 userDf.filter(userDf.col("price").gt(1000)).show(); //Rule 3 - Print State in which max transaction taken place in Last 5 mins userDf.groupBy("state").count(); return null; } }); jssc.start(); jssc.awaitTermination(); } } 函数仍然是user.is_anoynymous()。使用默认身份验证模型时,一切似乎都很好。

views.py:

True

backends.py:

 from testapp.models import *
 from django.http import HttpResponseRedirect,HttpResponse,Http404,QueryDict
 from django.shortcuts import    render_to_response,  RequestContext         
from django.template import Context
from django.core.paginator import Paginator,QuerySetPaginator
from django.template.loader import get_template
from django.contrib.auth   import    logout,authenticate,login
from django.contrib.auth.views import *
from testapp.forms import *
from django.contrib.auth.decorators import login_required
from django.views.generic import ListView
from testapp.backends import EmailBackend
from testapp.backends import EmailBackend

def main_page(request):
    return render_to_response('main_page.html',{
        'user':request.user
    })

def loggedout(request):
    logout(request)
    return HttpResponseRedirect('/')

def custom_login(request):
    if request.method == 'POST':
        form = LoginForm(request.POST)
    if form.is_valid():
        email = request.POST['email']
        password =  request.POST['password1']

        cb = EmailBackend()
        user = cb.authenticate(email,password)
        # return HttpResponse(user.username)
        if user is not None:
            if user.is_active:
                login(request,user)
                return HttpResponseRedirect('/')
            else:
                return HttpResponse('USer is not Active')
        else:
            return HttpResponse('USer Not found')
else:
    form = LoginForm()
    page_var = RequestContext(request, {
        'form':form, 
    })
    return render_to_response('customlogin.html',page_var)`

settings.py:

from django.contrib.auth.models import User
from django.contrib.auth.backends import ModelBackend

class EmailBackend(ModelBackend):

    def authenticate(self,email= None,password= None):
        try:
            user = User.objects.get(email=email)

            if user is not None:
                if user.check_password(password):
                    return user
                else :
                    return None
            else:
                return None
        except User.DoesNotExist:
            return None

    def get_user(self,user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None`

main_page.html:

AUTHENTICATION_BACKENDS = ('testapp.backends.EmailBackend','django.contrib.auth.backends.ModelBackend')

现在,虽然在成功进行身份验证后调用了main_page.html,但主页{% extends "base.html" %} {% block title %}Welcome to Django Bookmarks{% endblock %} {% block head %}Welcome to Django Bookmarks{% endblock %} {% block content %} {% block customadd %} kskdsdsdl;sd {% endblock %} {% if user.username %} <p>Welcome {{ user.username }}! Here you can store and share bookmarks!</p> {% else %} <p>Welcome anonymous user! You need to <a href="/login/">login</a>.</p> {% endif %} {% endblock %} 始终为{{user.username}},因此main_page.html将以匿名用户身份打开。

view.py中main_page函数中的

None返回user.is_anonymous()。我犯了什么错误?重定向到main_page.html后,我应该看到用户已登录。

编辑1:上次我故意没有把我包含在views.py中的所有软件包都放进去,所以我现在更新了它。

2 个答案:

答案 0 :(得分:1)

Django提供login view。我建议您使用它而不是自己编写。

如果您使用Django登录视图,Django将使用您的身份验证后端,因为您已将其添加到AUTHENTICATION_BACKENDS设置。

您需要对后端进行少量更改 - 将字段名称从email更改为username,以使其与登录表单匹配。您仍然会根据他们的电子邮件过滤用户。

def authenticate(self, username=None, password= None):
    try:
        user = User.objects.get(email=username)

如果您继续使用自己的登录视图,我可以看到几个可能的问题。首先,您应该导入authenticate方法,然后调用它而不是实例化您的登录后端。

from django.contrib.auth import authenticate

def custom_login(request):
    ...
    user = authenticate(email=email, password=password)
    ...

其次,当您致电login(request, user)时,请确保您导入了正确的login方法,而不是我上面提到的login视图。

from django.contrib.auth import login

答案 1 :(得分:0)

抱歉,我的代码中没有发现任何明显错误。我建议您使用Python's logging来帮助解决此问题。

根据我自己使用电子邮件进行身份验证的痛苦经历,您需要不区分大小写,因为很多的人会进入他们的电子邮件:WhereEmail@likeThis.com。 :)

user = User.objects.get(email__iexact=email)

...或存储小写的电子邮件地址。我工作的一个项目最终导致了重复的条目。

此外,如果该查询成功,则用户永远不会是None,因此您可以跳过该测试并简化try-except块:

try:
    user = User.objects.get(email__iexact=email)
    if user.check_password(password):
        return user
    else:
        logger.debug('password check failed')

except User.DoesNotExist:
    logger.debug('user does not exist')

return None
相关问题