I've installed djangosocialregistration and it seemed like it was working fine for a while, but now I'm getting an error and I can't figure out where it's coming from. Inside my view I'm doing this to start looking at the API...
me = request.facebook.graph.get_object("me")
and I'm getting this...
'Facebook' object has no attribute 'graph'
After it quit working I rolled back a couple small changes I'd made, reset everything, deleted cookies and it's still not working. I'm running django 1.1.1 and it's slightly difficult for me to upgrade, not impossible though. I've been reloading a bunch trying to get it working, is there any possibility facebook throttles login connections on their end?
The Facebook class in the middleware of socialregistration looks like this:
class Facebook(object):
def __init__(self, user=None):
if user is None:
self.uid = None
else:
self.uid = user['uid']
self.user = user
self.graph = facebook.GraphAPI(user['access_token'])
If no user is set on __inii__ it will simply not set graph. In the Middleware this should be set via:
fb_user = facebook.get_user_from_cookie(request.COOKIES, getattr(settings, 'FACEBOOK_APP_ID', settings.FACEBOOK_API_KEY), settings.FACEBOOK_SECRET_KEY)
request.facebook = Facebook(fb_user)
So my guess that the cookie from Facebook is not set for your site. Maybe you add some debug logging to determine if there is a cookie from facebook or not.
Another guess would be that request.facebook is overwritten somewhere. Maybe you check this as well.
Related
Ok,
I'm developing a website where I'm using Django. The website is for creating and keep track of stock portfolios. I have the database and the basics of the website set up but I would like to use the TDAmeritrade API in order to get the stock information. How it works is the user is redirected to TD where they enter there Login and Password they accept the terms and get transferred to a redirect page of the local host (until it goes live). Which looks a little like this
"https://127.0.0.1:8000/?code=" with a huge code after the equals sign.
Finally, how would one create the URL destination in Django url.py file and store the code for AUTH Token
I've tried something like this: path('?code=', test_view, name='test'),
but had no luck but that could be because of this error (You're accessing the development server over HTTPS, but it only supports HTTP.)
Thanks in advance!
Side note: I've tried looking up how Paypal does there send back confirmation but all I could find were packages Pre-build for Django
I figured out the solution with the help of Moha369 in the comments, So shout out to him/her!
def home_view(request):
context= {}
user = request.user
if user.is_authenticated:
token = request.GET.get('code')
print(token)
return render(request, "home.html", context)
Django Docs that helped
I am using Flask-login with remember=False (the only cookie is the session cookie). When copy-pasting the session cookie after logging out, for some reason the session is still valid and the user is logged in. Even though the logged out session was deleted properly in the flask logout_user() function - meaning that the ["user_id"] was deleted from the session dictionary. It seems like the session is restored from the old cookie. can someone explain?
I do not really have a right answer for this yet, as I am investigating it myself, but there are a couple of points I would like to make here:
the logout_user() from Flask-login does not really seem to be invalidating the session. It just changes the 'session' cookie's value in the client (the browser). While in the backend this session is still alive.
An experiment to prove this would be: (a simple browser plugin like CookieManager can be used to perform this exercise)
login to the app
take a note of the 'session' cookie's value post successful login
now logout
now observer the 'session' cookie's value again. And you would
notice that it has now changed.
Replace this value with the 'session'cookie's value previously noted
in step 1 above.
Try visiting an internal authenticated page again.
Result : You would successfully be able to view an internal page without re-logging in, proving that the logout_user() never really invalidated the session but just changed the 'session' cookie in the client.
Howeverm, I am myself still taking a look into flask-login logout_user() definition and trying to make sense of it.
I had This issue too. After diagnosing what i found is the decorator #login_required *does not invalidate the User in server side after logout*, which is a security threat. This will be a cake walk for a Hacker to hack your application since they can easily extract all the request and header data from developer tool of your browser and can again send request to you server from outside of the application.For ex: If you have used any API in your application the it will be very easy for Hacker to get all the request data and resend a request using POSTMAN.
I solved this issue by creating a separate decorator "#authentication_required" and used in place of "#login_required". then it worked for me,though #login_required is supposed to do the same.
So basically while logging in i generated a random string(token) and sent to database and same string(token) is added to session of flask i.e session["token"]="akhfkjdbfnd334fndf" use any random string generator function.(session object is globally available if u r using flask . u can very well add any field to session). and while logout i again generate a string(token) and update the old token with newly generated token in database. So what #authentication_required will do is it will get the token from session object and the token which is present in database and try to compare the value. if both are same then only #authentication_required will let the client access api.and dont forget to do session.clear() after logout_user().
#---------------------------------------------------------------#
##authentication_required definition
def authentication_required(f):
#wraps(f)
def wrap(*args, **kwargs):
try:
user_id=session['user_id'] #assigning "user_id" from flask session object to a variable "user_id"
user=User_table.find_first(_id=user_id)#couhdb query syntax
#comparing api_token sent to session object at the login time with api_token in sent to database at login time. If both doesn't matches then user is redirected to login page.
if not session["token"]==user.token:
return redirect(url_for('login'))
else:
return f(*args, **kwargs)
except:
app.logger.info(Response('Request Did not came through header !', 401, {'WWW-Authenticate': 'Login failed'}))
return redirect(url_for('login_to system'))
return wrap
#---------------------------------------------------------------#
-------------------------------------------------------
login api code
#app.route('/login_to_system', methods=['GET', 'POST'])
def login_to_system():
form = LoginForm()
user = User_table.find_first(username=form.username.data)
login_user(user, remember=False)
try:
#Generating an random api_token at login time and will send to db
token_string=''.join(random.choices(string.ascii_uppercase + string.digits, k=14))
user.token=token_string #assigning token_string value to field api_token in database.
user.save() #saving the value in user table(using couch Db You can follow syntax as per you DB)
except Exception as error:
app.logger.error(str(error))
app.logger.info("before setting api_token in session")
session["token"]= token_string #adding a "token" to session object
#app.logger.info("Rendering login form")
return render_template('login.html', title='Sign In', form=form)
#-------------------------------------------------------#
#-----------------------------------#
#logout api code
#app.route('/logout')
def logout():
try:
user=User_table.find_first(_id=user_id)
#Generating a random token while logging out and will overwrite eariler token sent at login time send to database.
user.token=token_string=''.join(random.choices(string.ascii_uppercase + string.digits, k=17))
user.save()
except Exception as error:
app.logger.error(str(error))
logout_user()
session.clear()#clearing session
return redirect(url_for('Home page'))
#-----------------------------------#
Note: Seems like login_required is not working fine for me thats why i had to create another decorator but login_required also does the same thing but its strange that it not working for me.
As the question says, I'd like to set some variable to user session when the user get logged and remove this variable on logout or browser close.
Initially I thought to write my custom login view to achieve this, but probably a middleware is a better solution.
The middleware wasn't the right way to achieve the solution. I discovered the signals and I implemented my solution in this way:
#receiver(user_logged_in)
def sig_user_logged_in(sender, user, request, **kwargs):
moderator = get_or_none(CompanyModerator, moderator__user=request.user)
if moderator:
if 'company_id' not in request.session:
request.session['company_id'] = moderator.company.id
The difference is that a middleware is triggered on each django request, when the needs was just do something when the user get logged-in/out. Each time that an user get logged-in/out we add some data/object-models etc.. to the session to track the user all around the website.
What do you think?
After going through all the comments to your question, I would also say the same as #akhil viswam in his last comment.
But now that you specified that you do want to do some custom tasks, then you can write your own custom middleware like this -> https://github.com/ankushrgv/notification/blob/master/apps/accounts/middlewares.py
and then include it in your settings.py like this -> https://github.com/ankushrgv/notification/blob/master/config/settings.py
Basically I was writing the user_id : session_id key value pairs in Redis and then reading them in my views to show real time notifications but only to the logged-in users.
I hope this will give you a fair idea about how to write your own custom middleware.
Am trying to keep track of AnonymousUsers by their session information (if possible).
In older versions of Django, I could do something like:
def my_view(request):
# in case the user wasn't logged in, create/save a session
if not request.session.session_key:
request.session.save()
# would give me the key and on the next load it would persist
session_key = request.session.session_key
But with 1.6 (and I've been out of the game for a while) this results in a new unique session ID each time the request is put through. There is no persistence. I've tried to do a little reading but am going in circles as I'm out of Django practice.
How do I have a session persist? Do I need to write my own cookie handling?
So, after I started reading through the source code I found myself on the global_settings.py file and found this gem:
SESSION_SAVE_EVERY_REQUEST = True
When I added that to the settings.py file my problems were solved. AnonymousUsers got a session_key. Yipee!
I'm trying to figure out how to test middleware in django. The middleware I'm writing logs in a user under certain conditions (if a key sent in email is valid). So obviously I'm dependent on django.contrib.auth and django.contrib.sessions.
I'm running into problems testing the login portion. I'm making a request like this:
user = User.objects.create_user('user', 'user#example.org', 'password')
key = LoginKey.objects.create(user=user)
request = self.factory.get('/', data={'auth_key': key.hash}) # self.factory is a RequestFactory()
self.middleware.process_request(request) # self.middleware is MyMiddleware()
That fails due to the session not being set. So next, I wrote a little snippet in my test class:
def make_session(self, request):
SessionMiddleware().process_request(request)
and that fails due to 'User' object has no attribute 'backend'. I'm not sure on the meaning of that, but I suspect I need to run all the middlewares I have installed.
I don't really want to make a fake view for this just to run a middleware, but I can't see another option at this point.
So I just wanted to know, before I have to chase this rabbit all the way down the hole, is there a way of doing this that doesn't require as much duct tape?
You should use the test client for this. That will ensure that the middleware is run and the session keys created.
response = self.client.get('/?auth_key=%s' % key.hash)
self.assertTrue(response.context['user'].is_authenticated()) # for example