How do I make cookie sessions? - django

I'm trying to make a cookie session and can't find anything thats resembles clear documentation. The django docs on this are very weak!
Alls I found was this guys video on cookies: http://www.youtube.com/watch?v=U_dDY7TvJ4E
Can someone show me how to make a cookie when a visitor goes to my site?
I want be able to save that cookie in my database, so that when they make another request I can associate changes with them server side.
Thanks!

Here is the link for where in the Django Docs on how to make cookies:
https://docs.djangoproject.com/en/dev/topics/http/sessions/
A short example of how to do so would be like so. You can use the built in Session table as a dictionary like so:
def myView(request):
request.session['foo'] = 'bar'
# other view code
render(request, 'mypage.html')
UPDATE:
This is how you would redirect a User based on if they have a Cookie or not
def myViewTwo(request):
id = request.session['UUID1']
# verify the UUID1 exists
if id == 'UUID1:
return render(request, 'cookie.html')
# if not, send them to a normal view
return render(request, 'no_cookie.html')

Related

Django - Is there a way to configure certain url to be inaccessible from browser request?

I've searched for this question but could not found an answer.
Basically, let's say i have my_app/successfully_page that i want to be displayed within the application flow. I don't want that to be displayed if some one is typing into browser the direct url.
How can i make that url page INACCESSIBLE from browser search?
You can do it using request.META.get('HTTP_REFERER') in order to check from which url the user is coming. If this is not the authorized url, then you can redirect the user:
if request.META.get('HTTP_REFERER') == my_url:
# Do something...
else:
# Redirect...
Check the doc here: https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.META
I had some kind of same problem before , I solved it using sessions in the page before that set a session on the request and in the views of the url which needs to be inaccessible by direct browser set a if condition on it.
This need to be set in view of before page
request.session['is_accessible'] = True
And in the page u want to make the condition like
if (request.session['is_accessible'] == True):
redirect("Your_page_url.html")
else:
redirect("Page you want to show .html")
And if you are thinking that a page needs to be accessed only on login then there is a decorator in Django itself like
from django.contrib.auth.decorators import login_required
#login_required(login_url='/login.html')
def yourfunction(request):
return Httpresponse("Your page")
And if u have more problem in it u can write an email to me at kiranu941#gmail.com
You have to use user agent that will let you know the perfect output.
request.META['HTTP_USER_AGENT']
But I would also recommend you to take a look at the Django User-Agents library.
You can find more relevant examples over the link.

Get token from URL in Django. TDAmeritrade API Call

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

how can i store this created cookie key in a variable in django

request.session.set_test_cookie() <---- this will create a session with cookie id
but how can I store this cookie key in a variable in Django.
I've tried this, but it gives error.
id = request.session.set_test_cookie()
Django provides an easy way to test whether the user’s browser accepts cookies. Just call the set_test_cookie() method of request.session in a view, and call test_cookie_worked() in a subsequent view – not in the same view call reference.
so set_test_cookie() method is only for testing a is browser support cookie or not. if you want to check is browser support call session.test_cookie_worked() method
Create cookie in django as follow:
def view(request):
response = HttpResponse('response data')
response.set_cookie('cookie_name', 'cookie_value')
Retrieve cookie data:
def view(request):
if 'cookie_name' in request.COOKIES:
value = request.COOKIES['cookie_name']

flask-login reusable cookies

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.

Django: any way to avoid querying for request.user on every request?

For my website pretty much every page has a header bar displaying "Welcome, ABC" where "ABC" is the username. That means request.user will be called for every single request resulting in database hits over and over again.
But once a user is logged in, I should be able to store his user instance in his cookie and encrypt it. That way I can avoid hitting the database repeatedly and just retrieve request.user from the cookie instead.
How would you modify Django to do this? Is there any Django plugins that does what I need?
Thanks
You want to use the session middleware, and you'll want to read the documentation. The session middleware supports multiple session engines. Ideally you'd use memcached or redis, but you could write your own session engine to store all the data in the user's cookie. Once you enable the middleware, it's available as part of the request object. You interact with request.session, which acts like a dict, making it easy to use. Here are a couple of examples from the docs:
This simplistic view sets a has_commented variable to True after a user posts a comment. It doesn’t let a user post a comment more than once:
def post_comment(request, new_comment):
if request.session.get('has_commented', False):
return HttpResponse("You've already commented.")
c = comments.Comment(comment=new_comment)
c.save()
request.session['has_commented'] = True
return HttpResponse('Thanks for your comment!')
This simplistic view logs in a "member" of the site:
def login(request):
m = Member.objects.get(username=request.POST['username'])
if m.password == request.POST['password']:
request.session['member_id'] = m.id
return HttpResponse("You're logged in.")
else:
return HttpResponse("Your username and password didn't match.")
This smells of over-optimisation. Getting a user from the db is a single hit per request, or possibly two if you use a Profile model as well. If your site is such that an extra two queries makes a big difference to performance, you may have bigger problems.
The user is attached to the request object using the Authentication Middleware provided by django (django.contrib.auth.middleware). It users a function the get_user function in django.contrib.auth.init to get the user from the backend you are using. You can easily change this function to look for the user in another location (e.g. cookie).
When a user is logged in, django puts the userid in the session (request.session[SESSION_KEY]=user.id). When a user logs off, it erases the user's id from the session. You can override these login and logoff functions to also store a user object in the browsers cookie / erase user object from cookie in the browser. Both of these functions are also in django.contrib.auth.init
See here for settting cookies: Django Cookies, how can I set them?
Once you have proper caching the number of database hits should be reduced significantly - then again I'm not really and expert on caching. I think it would be a bad idea to modify request.user to solve your problem. I think a better solution would be to create some utility, method or custom template tag that attempts to load your require user data from the cookie, and return the result. If the user data is not found in the cookie, then a call to request.user should be made, save the data to the cookie, and then return the result. You could possibly use a post_save signal to check for changes to the user data, so that you can make update to the cookie as required.