我的主要要求是进行电子邮件身份验证。虽然我的自定义身份验证后端似乎工作正常,但即使在使用我的自定义后端成功进行身份验证后,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将以匿名用户身份打开。
None
返回user.is_anonymous()
。我犯了什么错误?重定向到main_page.html后,我应该看到用户已登录。
编辑1:上次我故意没有把我包含在views.py中的所有软件包都放进去,所以我现在更新了它。
答案 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