I'm developing a chrome extension and I need to get all cookies (at least in the current CookieStore). First pass, I use
chrome.cookies.getAll({}, function (cookies) {
chrome.cookies.onChanged.addListener(function (changeInfo) {
// do stuff with added/removed cookies here ...
};
// do stuff with all the original cookies here ...
});
But now I'm thinking there may be a flaw here: the getAll call asks the browser to list all the existing cookies. The browser then calls the getAll callback with an array of these existing cookies. The extension then registers to get updates for any added/removed/changed cookies. It appears that any cookie which is added by the browser after it creates the cookies array (e.g. via active tabs), but before the addListener call executes, will be lost until updated.
Does anyone have suggestions on a better approach?
I started looking through the chrome dev tools source for examples, but it appears the Resources > Cookies table does not use this API.
Related
Sorry guys, I'm really new to sessions and cookies and I'm trying to understand the mechanism behind it. I wanted to add register/login to my simple website and in order to do I need to understand web authentication and I really think I will have tons of questions regarding this topic.
Initially, I have register page that sends info after clicking submit button to a node server using express.
I'm trying to see what happens, so I've created a session in post route, it's created in the browser (connect.sid), then I commented out the part that creates that session and just tries to redisplay the session object, but it's undefined, but I still can see the session in the browser's cookies section, so what's going on? Thanks
app.use(session({
secret:"my test secret",
cookie:{},
resave:false,
saveUninitialized:false
}))
app.post("/register", (req, res) => {
req.session.usertest = "testsession_hardcodedvaluefornow";
console.log(req.session.usertest); // -> this is okay when above line to create is uncommented
//but when I comment the session assignment, it becomes undefined?
res.send("In register...");
})
I can see the session cookie even after commenting out the create session and posting over and over.
connect.sid s%3A_TahsTv0xhY-iHIdjDRblYJ_aZZ5oiSd.do7JcOGR1FaXPcFFIQ6hg5AW%2B0XVsYwIRO8vndyjDzs
req.session.id produces a different value (not undefined) even if I delete my session in the browser, so not sure where that comes from.
There is no "usertest" key in the session object, therefore it is undefined. The reason it's not undefined when you uncomment that line is because you create that key yourself in that instant with that line.
You can get the whole session object by using req.session, the session id by using req.session.id and the session cookie by using req.session.cookie.
Edit
To further clarify: a session will be made for every connected client. That is why you can see the cookie in the browser. That has no meaning however, it's just a way to uniquely identify that client (without actually telling you who that client is). Any information about that session (whether they're logged in, user id,...) needs to be stored in a session store. Express-session will use memory store by default, if the server restarts all that information will be lost, which is why that key doesn't exist. In order to preserve that information it has to be stored in a persistent session store. More information on session store implementations for express-session and how to use them can be found here: https://www.npmjs.com/package/express-session
As for the cookie values you get, those are the default ones set by express-session since you haven't set any yourself. You can change the maxAge to let it expire (or set it so 10 years or more for a more persistent session), you can specify a domain to which that cookie belongs, you can set it to secure (to only allow it over secure connections, e.g. https) and httpOpnly is by default true. httpOnly cookies cannot be accessed/altered by the client (although you can see them in the browser), do not set this to false.
Background Information
I am working on a NodeJS w/ Express project.
I am using some auth middleware, we can call it isAuthenticated()
The middleware is just protecting certain routes w/ passport, etc.
I am adding a file download link that is visible when a user is not authenticated yet. (i.e. the button is publicly visible).
If you click the button, the download route is protected, so we redirect you to a sign in page.
The Problem
Once the user authenticates, I am calling res.download(file);. The download works fine, but the user is still at the sign in page with their credentials typed in. (Note: the user is authenticated, but no further redirect is happening on this route). If I try res.download(file) and then make a call to res.redirect('/'), the file isn't downloaded.
Basically: I want to redirect the user to the home page at 'website.com/', but the approaches I've taken haven't worked.
Main Approach:
Set res.local.downloadFile2 = true in the router.get('/download/file2') route. Then redirect to home using res.redirect('/'). Now, in the home route, I would just do the following after rendering the home page again.
if (res.locals.downloadFile2 === true) {
res.download(file2)
}
However: res.locals.downloadFile2 === undefined when that check is being done. I've tried to step through and somewhere it is being reset in one of the _modules I am using, so this is not working. I am currently unsure of the cause.
I could probably solve this by not displaying the links until a user is Authenticated, then there shouldn't be any cases of redirecting to login and back again, which means they would never see the login page, etc. but that is not the right solution to this problem, and is not the one I want to implement.
I would really appreciate any help, and can provide more information if needed!
Thanks in advance.
The issue is that after the redirect, the res object is a complete new object due to the browser issued a new request to follow the redirect. That's why res.locals.downloadFile2 is undefined.
To solve your problem, you can replace your code res.local.downloadFile2 = true with code to set a cookie. The cookie holds information which will be stored on client side by the browser and send to the server with every request.
See cookies npm package for example:
var Cookies = require('cookies');
var cookies = new Cookies(req, res, { keys: ['arbitrary string to encrypt the cookie'] })
// get value of the cookie
var need_to_download_file = cookies.get('need_to_download_file', { signed: true })
// Logic to download file (if necessary)
if (need_to_download_file) {
// Trigger download of the file
// Reset cookie
cookies.set('need_to_download_file', false, { signed: true })
}
// set the cookie
cookies.set('need_to_download_file', true, { signed: true })
I am very new to electron so I may be going about this all wrong.
We have a few web apps internally that are all working and I wanted to practice by building one of them into electron.
What I need to do is load our SSO login page within the app and then listen for a cookie/session to be created after authentication has been successful.
I am using a webview like so:
<div style="width:100%; height:100%">
<span class="loading loader" id="loading" name="loading"></span>
<webview class="ssologin" src="https://example.com/resources/ldap.php" autosize="on" style="min-width:755px; min-height:640px"></webview>
</div>
This loads the login page for ldap/sso. After I login, it would normally take you to the web application you were going to before you were re-routed to SSO do to not having a valid session.
I am trying to figure out how I can listen for a cookie/session so that I know that they have authenticated and we get a response back.
Essentially, I need this valid session in order to make future API calls in the app to endpoints so I want to try and use this existing authentication implementation without having to include other modules and mess with all that.
Any suggestions?
Just in case you didn't know: Electron does not currently recommend to use <webview>:
We currently recommend to not use the webview tag and to consider alternatives, like iframe, Electron's BrowserView, or an architecture that avoids embedded content altogether.
Cf https://electronjs.org/docs/api/webview-tag#warning
You probably need to set a partition on your <webview>:
<webview src="https://github.com" partition="persist:github"></webview>
<webview src="https://electronjs.org" partition="electron"></webview>
Sets the session used by the page. If partition starts with persist:, the page will use a persistent session available to all pages in the app with the same partition. if there is no persist: prefix, the page will use an in-memory session. By assigning the same partition, multiple pages can share the same session. If the partition is unset then default session of the app will be used.
Cf https://electronjs.org/docs/api/webview-tag#partition
With that you can (from the main process) access the cookie of the session:
const {session} = require('electron');
const sess = session.fromPartition('persist:foobar');
const cookies = sess.cookies;
Then you can listen for changed events on that cookie object:
Emitted when a cookie is changed because it was added, edited, removed, or expired.
cookies.on('change', () => {
// do something when your SSO cookie is set
});
Cf https://electronjs.org/docs/api/cookies#event-changed
I'm learning Angular with a MEAN stack project. Full code is here: Angular front-end, Node.js API.
On the back-end, I use Passport authentication with the default session-based behaviour, and I have local, Google and Facebook strategies set up. Passport will insert user data in the session cookie, to be parsed and used by the front-end to display user name, email address, profile pic, etc.
So now in the back-end, what I need to do is retrieve the cookie and deserialize it, then write methods to use said cookie to get user data, as well as a basic isLoggedIn(), that would just check if a valid cookie is present.
To do that, I've tried both ngx-cookie and ngx-cookie-service and have the same problem with both: I can create and read a cookie that I've created, but the 'session' and 'session.sig' cookies created by Passport remain invisible to the getAll method (and any get('session')).
All code handling that is inside authentication.service.ts. Currently all methods are meant for a token-based auth, so I need to change them. Specifically, this is the method I use to test cookie handling:
public getCookies() {
this.cookies.set('test', 'yay');
console.log('test: ', this.cookies.check('test'));
const allCookies = this.cookies.getAll();
console.log('allCookies: ', allCookies);
return allCookies;
}
The console output of that code shows only one cookie, 'test'. On the browser dev tools, I see there are two more cookies, 'session' and 'session.sig', that I want access to. But how?
Thanks!
I am building a react web application with a separate back-end express api that manages all the calls, including passporting and setting cookies. Let's call the back-end service 'api.com' and the front-end service 'react.com'. I'm using passporting with an existing provider (spotify) and after the authorization succeeds, a cookie is set on api.com. The idea is that the user interacts with react.com and requests are made to api.com via a proxy.
If I'm just testing in my browser and I make a call to api.com/resource, the cookie is automatically set. I know this because I've added a bit of logging and also because the requests that require authorization are succeeding via the cookie.
However, when I make calls to api.com from react.com via the proxy, the cookie is not set. Is this expected behavior when proxying? It seems odd that the cookie is set when I call api.com directly, but it is not set when it is redirected. Is there a way around this? My thought would be to communicate the cookie from api.com to react.com, save it there, and send it on all subsequent requests, but that seems overkill. I'm also wondering if maybe I should be setting the cookie on react.com instead of api.com.
I've tried in both Firefox and Chrome, and if it makes a difference, I'm using axios for the requests on react.com.
const request = axios({
method:'get',
url:'/api/resource'
});
This gets proxied as follows (still on react.com), using express-http-proxy:
app.use('/', proxy('api.com', {
filter: (req) => {
return (req.path.indexOf('/api') === 0);
}
}));
But once this hits api.com, any authentication fails, because the cookie is not present.
Any help is appreciated
As far as I have understood your question, I think you're not considering that cookies are set to host name.
So in the first case the hostname is same and its okay, but in the second case the browser's cookies are not set for react.com
So trying to set the cookie on react.com should work.
I would have asked for a clarification using a comment but I don't have enough reputation for that yet.