You know, web applications needs sessions or cookies to authentication. I trying to build web application with Vue.JS and Flask microframework for example ERP or CRM.
I'm confused. How can I work with sessions? Let's think we have a code like this in the Flask:
import os
from flask import Flask, request, jsonify, abort, session
app = Flask(__name__)
app.config['SECRET_KEY'] = os.getenv('SECRET_KEY') or \
'e5ac358c-f0bf-11e5-9e39-d3b532c10a28'
#app.route('/login', methods=['POST'])
def user_login():
user = request.form['user']
session['isLogged'] = True
return jsonify({'status': session['isLogged']})
#app.route('/user-info')
def user_info():
if 'isLogged' in session:
return jsonify({'user': 'ali'})
else:
return jsonify({'error': 'Authentication error'})
and our front-end codes should be like this:
mounted() {
this.checkIsLogged();
},
methods: {
checkIsLogged() {
fetch('http://127.0.0.1:5000/user-info', {
mode: 'no-cors',
method: 'GET',
}).then((resp) => {
return resp;
}).then((obj) => {
if(obj.user) {
this.status = true
}
})
},
login() {
let frmData = new FormData(document.querySelector("#frmLogin"));
fetch('http://127.0.0.1:5000/login', {
mode: 'no-cors',
method: 'POST',
body: frmData,
}).then((resp) => {
return resp;
}).then((obj) => {
this.status = obj.status
})
}
}
Everything is normal until I refresh the page. When I refresh the page, I lose the sessions.
Server-side sessions are important for many reasons. If I use localStore or something like that how could be secure I have no idea.
I need some help who worked on similar projects. You can give me suggestions. Because I never worked similar projects.
Other stuff I've read on this topic:
Single page application with HttpOnly cookie-based authentication and session management
SPA best practices for authentication and session management
I'm still confused to about what can I do.
Session handling is something your SPA doesn't really care much about. The session is between the user-agent (browser) and the server. Your vue application doesn't have much to do with it. That's not to say you can't do something wrong, but usually the issue is not with your front end.
That being said it's tough do give an answer to this question because we don't really know what's wrong. What I can do is give you instructions on how you can diagnose this kind of problem. During this diagnosis you'll figure out where the actual issue is and, at least for me, it usually becomes obvious what I need to do.
Step 1)
Use some low level HTTP tool to check the Server response (personally I use curl or Postman when lazy). Send the login request to the server and take a look at the response headers.
When the login is successful you should have a header "Set-Cookie", usually with a content of a "sessionid" or whatever key you're using for sessions.
If you don't see a "Set-Cookie" one of the following is true:
Your server did not start a session and thus did not send a session cookie to the client
there's a proxy/firewall/anti-ad- or tracking plugin somewhere filtering out Cookies
If you see the Set-Cookie Header continue with Step 2, otherwise check the manual in regards to sessions in your chosen backend technology.
Step 2)
Thankfully most modern browsers have a developer console which allows you to do two things:
1) Check your HTTP request headers, body and response headers and body
2) Take a look at stored cookies
Using the first feature (in Chrome this would be under the "Network" tab in the developer console) diagnose the request and response. To do so you need to have the developer console open while performing the login in your app. Check the response of the login, it should contain the Set-Cookie if the login was successful.
If the cookie is not present your server doesn't send it, probably for security reasons (cross-origin policies).
If it is present, the cookie must now be present in the cookie store. In chrome developer console, go to the "Application" tab, expand Cookies from the left menu and take a look at the hosts for which cookies are present. There should be a cookie present which was set in the step before. If not the browser didn't accept the cookie. This usually happens when your cookie is set for a certain domain or path, which isn't the correct one. In such a case you can try to set the domain and/or path to an empty or the correct value (in case of the path a "/").
If your cookie is present, go to step 3
Step 3)
Remember when I said the app has nothing to do with the session. Every request you send either with ajax or simply entering a valid URL in the browser sends all cookies present for this host in the request headers. That is unless you actively prevent whatever library you're using to do so.
If your request doesn't contain the session cookie one of the following is usually true:
the usage of your http library actively prevents sending of cookies
you're sending a correct request but the cookie-domain/path doesn't match the request host/path and is thus not sent along
your cookie is super shortlived and has already expired
If your cookie is sent correctly then your sessions handling should work unless your server doesn't remember that session or starts a new session regardless of an existing session.
I realise this question is quite old and this extensive answer comes way too late, however someone with similar problems may be able to profit from it.
Related
Firstly, I did add the line CookieManager.check.cookies=false to jmeter.properties.
What I'm Trying to Do
I want to add a cookie to a request's existing cookies.
For example, I see the request has [edited]:
Cookie Data:
c1=sfasfsfsfsfs; c2=erqwerqwrr; c3=poiuopiupoi
Expected Results
I would like it to have:
Cookie Data:
c1=sfasfsfsfsfs; c2=erqwerqwrr; c3=poiuopiupoi; partner=favicon.ico
Here is what I tried:
BASE_URL_2 is a variable defined in the form qa.company.com.
Actual Results
Whatever I have tried so far has not made any change in the cookies.
What else shall I try?
Underlying Motivation
Recorded a Web session and played it back.
Added a RegEx Extractor to pull out a token and then added it to subsequent requests. That helped.
However, certain requests failed with an custom application exception Security violation, please refresh.
Probably session login state is not being passed, so the website thinks the call is "stale".
I've seen this on the GUI when the session expires and you try to click a button on the site.
On comparing the cookies seem in JMeter with what I saw in the Chrome Debugger, it was clear that there were more cookies in the running application than what I had in JMeter.
Are you sure you're using HTTPS protocol because if you have secure flag and using HTTP protocol - the cookie will not be sent.
Also remove = from partner= otherwise you will end up with partner==favicon.ico
Demo:
More information:
Using HTTP cookies
HTTP Cookie Manager Advanced Usage - A Guide
In a Chrome warning, it says:
Specify SameSite=None and Secure if the cookie should be sent in cross-site requests. This enables third-party use.
How do I do this correctly using express-session?
app.use(
cors({
credentials: true,
origin: ["http://localhost:3000", "https://elated-jackson-28b73e.netlify.app"] //Swap this with the client url
})
);
var sess = {
secret: 'keyboard cat',
cookie: {}
}
if (app.get('env') === 'production') {
app.set('trust proxy', 1) // trust first proxy
sess.cookie.secure = true // serve secure cookies
sess.cookie.sameSite = 'none'
}
app.use(session(sess))
you are getting this because you are using a resource from another site and that server is attempting to set a "cookie" but, it does not have the SameSite attribute set, which is being reported in newer versions of browsers.
this (may) also be shown if you are trying to access the server page from local computer (xampp), which generally doesn't has SSL installed;
set the header line in your server page (if in PHP) as below:
header("Set-Cookie: cross-site-cookie=whatever; SameSite=None; Secure");
(remember: this must be solved from the server side.)
i got the same issue when run my code in localhost. The affected resource is _ga, _gid, _utma, _utmz. All of them from unpkg.com
and i got marker image leaflet failed request but doesnt affect the page.
since i dont understand what the specific problem so i just delete the affected resource cookies in inspect element and the code will run without notif again.
thought i know if it's better to not answer based by personal experience. just tell me if it's not help at all.
If you are using Google login button or any other identity service add this:
<GoogleLogin onSuccess={() =>()} onError={() => ()} cookiePolicy='single-host-origin'/>
In my Auth API set the ss-id cookie domain to be used for all subdomains like so in my AppHost.Configure method:
Config = new HostConfig
{
RestrictAllCookiesToDomain = ".mywebsite.com"
};
My browser will include this cookie in every request to every every subdomain API of mine, for example: user.mywebsite.com.
Unfortunately, my APIs are responding with SET COOKIE responses, intermittently!
So sometimes I get what I do not want with my ss-id Cookie:
And sometimes, logging in and out, clearing my cookies for mywebsite.com I can get what I want and my APIs are sharing the same cookie:
I have attempted to add:
Config = new HostConfig
{
RestrictAllCookiesToDomain = ".mywebsite.com"
};
To other APIs' AppHost.Configure but this does not seem to remedy the situation, nor does it seem necessary because the ss-id cookie set by my auth API successful login response is for all subdomains (.mywebsite.com)
I am suspecting that Ajax requests are being sent to APIs without the ss-id cookie have been set yet, a timing issue across multiple Ajax requests and the login process.
Is my logic correct? Since the ss-id SET COOKIE domain in the response header for the initial response is .mywebsite.com after login that none of my other APIs will respond with a new SET COOKIE for ss-id?
You’re not going to know what’s happening unless you view the raw HTTP Headers to see what’s actually happening.
It’s possible there’s a race condition with multiple Ajax requests which we’re initially sent without ss-id cookies in which case they can have different ss-id cookies returned in which case the last Set-Cookie instruction will win and be used going forward provided they all use the same / path.
I am developing an application for my AppleTV. The App will read movies from an online website that hasn't developed any API for this kind of thing.
I use XMLHTTPRequest to get the different URLs and have the user search for his movie, etc... Everything is working fine, except for a single request. To get the movie URL, I have to send a get request to a specific address (let's say http://example.com/getmovie.html) with a constant cookie (let's say mycookie=cookie).
I've tried using setRequestHeader:
var xhr = new XMLHttpRequest();
xhr.open("GET", url, false);
xhr.withCredentials = true;
xhr.setRequestHeader('Cookie', 'mycookie=cookie');
xhr.send();
But no cookie seems to be sent.
I also tried setting the cookie with Document.cookie like I would have probably done in a "normal" js script (running in my browser) but no luck either.
This is extremely frustrating, especially since I'm stuck so close to the end of my app.
I guess cross-origin might be the issue but I'm able to get URLs without issues if I don't have to set cookies, so I am a bit lost there.
Please let me know how I can get http://example.com/getmovie.html with a specific cookie header.
Thanks for your help
im sorry to inform you but the xmlHTTPRequest function of javascript does not allow a cookie header to be set for security reasons as shown here: Why cookies and set-cookie headers can't be set while making xmlhttprequest using setRequestHeader? the best way i could see you making that get request would be to a proxy server that you would be running. I believe that it is built this way to prevent you from setting cookies on domains that you do not own, furthermore i do not see an alternate resolution to this problem as no were in the docs i looked at was cookie persistence or management mentioned
In case someone has the same issue:
I didn't find a solution to sending a cookie with javascript. However, in my situation, the origin of the request didn't matter, only the cookie did. My solution was then to create a PHP file receiving the destination URL and the cookie content as parameters, and then sending the get request with the cookie as a request header. (more information about how to do so here: PHP GET Request, sending headers).
In my javascript I then use XMLHttpRequest to connect to my PHP file (hosted online) with simple get parameters and I then receive the response from the PHP. That trick of course won't work if the origin of the request matters (except if you host your file at home I guess, but in my case I want my application to work even if my WAMP isn't on).
Well... the problem here is the line xhr.setRequestHeader('Cookie', 'mycookie=cookie'); line just because the 'Cookie' header is reserved for the client browser to send the stored cookies. This means you are trying to do what the browser already does. When you send a any request, the client browser automatlycally will take all the cookies related to the site you are requesting and put them on the 'Cookie' header, you don't need to do anything else, if your cookie exist in your browser, it will be send.
Cordova how to send session cookie, allow credentials with XMLhttprequest:
// JS
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://example.com/ajax.php', true);
xhr.withCredentials = true;
xhr.onreadystatechange = function() {
if(xhr.readyState == 4 && xhr.status == 200) {
// alert(xhr.responseText);
// Get header from php server request if you want for something
var cookie = xhr.getResponseHeader("Cookie");
// alert("Cookie: " + cookie);
}
}
xhr.send();
// Php
// You can add cookie to header and get with (session works without it)
header('Cookie: PHPSESSID='.$_COOKIE['PHPSESSID']);
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: Origin, Content-Type, Accept, Authorization, X-Request-With, Set-Cookie, Cookie, Bearer');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 86400');
I am making a (forms)authentication module(HTTPModule) for IIS that reads authentication from the login page, sets a cookie and redirects. All works great on all sites and sub applications. Because the module also protects webservices I build in a part that also reads the authorization header. Because these services should also be accessed from other tools.
Now I got to the point I actually protect a webservice, all great and with the auth header to the request I can indeed always get to the webservice but I can ONLY access it with the header active(and after every request I get another cookie).
If I try to access it with my normal login, where I also access other sites under the same protection with then I get redirected back to the login page :S. I really do not understand why this is happening.
PS HttpContext.Current.Request.IsAuthenticated is always false in my module when accessing the service, but my code is:
if(!HttpContext.Current.Request.IsAuthenticated){
if(Forms["Username"] != null){
//do authenticatoin & setCookie and Principle
}
}else{
if(AuthHeader is there){
//do authenticatoin & setCookie and Principle
}
}
Naturally with every request now it authenticates and sets the principle for each request. But why oh why does it not see(send) my cookie while other applications do see it? (with the exact same module)
The OnAuthenticateMethod also does not receive the FormsAuth ticket/cookie but does receive other cookies I set.
Things I already checked:
* web.config authorization is correct.
* Machine keys are set for cookies.
* Cookie names are similar
* .ASPXAUTH cookie does not get send towards OnAuthenticateMethod, but it does get send by the browser in the Cookie header.
I am lost on why this happens.