Cookie / session issue with safari browser using atlassian-connect-express and redis

269 views
Skip to first unread message

lutz

unread,
Mar 1, 2017, 9:57:43 PM3/1/17
to Atlassian Connect Dev
Hi, i'm posting my question again here because answers.atlassian.com is down for the moment (since hours) => 'Down for Maintenance' and i need to solve this problem asap.

I'm develop an confluence addon with ACE + Postgres DB + Redis.
For using Redis, the addon needs to able to store an cookie at the client side.
 
I've tried may 10 different ways to store such kind of cookie in a safari client but with no success. FF and chrome and IE are OK.
One of these test was this one:

But it stores a cookie under .atlassian.net Domain with the key/value:
Key: AJS.conglomerate.cookie
Value: "atlassian-connect-test-addon$$my_cookie=my value"

So i'm quite frustrated about this behavoir, so may be somebody can help me.
I only need kind of session-store which is compatible with most modern browsers.

Thank you for your support.

regards
lutz

Daniel Wester

unread,
Mar 1, 2017, 10:31:51 PM3/1/17
to Atlassian Connect Dev
Ahhh... Third party cookies. As a regular awesome they're evil because anyone can track you - as a developer of a system - they're awesome!

So the bad news, you can issue a cookie yourself - but it more than likely won't be accepted thought by the end user though since you're in an iframe and most browsers today don't accept third party cookies by default - so you'll need to take that behavior as something that will happen to you (because even 5% of users not having the proper behavior is bad).

So... back to the issue at hand. AP.cookie is awesome, but like you said - it issues the cookie on the atlassian.net domain(we won't go into the number of cookies on atlassian's domains nowadays) so it really only works for javascript driven apps. Because of third party restrictions though, there really aren't any alternatives.

If you can have a barebones page loading that then can grab the session id from AP.cookies and then do an ajax query to redis and pass the value on the query string, you should be able to get around it. In the same way - you can have an ajax call on the page that calls the redis store and extracts the cookie header and then calls the AP.cookies through it.

It's not what you want to hear, but it's a limitation of browsers, iframes and cookies and something we have to live with... :( (Or you canjust ignore it and tell users that have the problem to change their settings, which more than likely most users won't though :( ).

/Daniel

lutz

unread,
Mar 2, 2017, 6:34:14 PM3/2/17
to Atlassian Connect Dev
Hi Daniel

I've tried to implement your idea but how can i retrieve the encrypted session id from redis ? redis can't talk over http.
What i can do is to have an default route endpoint like /init grab the session id (req.session.id) and pass it back to the client.

The session id (req.session.id) looks like n5RJlmiYO_LMhP0zPx7HpX0j9n0V503v but in the session cookie the id looks s%3An5RJlmiYO_LMhP0zPx7HpX0j9n0V503v.%2BPM7gFMKM3%2Fs3KikRKmYcVIRpnT7aGKzJobFR1YKLZk.
So it's a kind of hash signature appended to the id itselfs.

Any ideas how to solve this issue ?

Regards
Lutz

lutz

unread,
Mar 2, 2017, 6:34:14 PM3/2/17
to Atlassian Connect Dev
It's me once again.
Okay, now im able to pass the signed session-id from ap.cookies read back to server as query param.

sign the current session-id serverside

function renderSafariWorkaround(req, res) {

   
var cookie = require('cookie-signature');
   
var redisConfig = addon.config.redis();
   
var secret = redisConfig.secret;
   
var sessionID =cookie.sign(req.session.id, secret);

   
encodeUri = encodeURIComponent(sessionID);

    res
.render('safari-view', {
       
sessionID : encodeUri
    });
}




safari-view.hbs

<script>

    $
(function() {
        AP
.require('cookie', function (cookie) {

            cookie
.save('atlassian-addon-session', '{{sessionID }}', 1);

            $
.ajax({
               
url: '{{localBaseUrl}}/editor?jwt={{token}}&safari={{sessionID }}',
               
type: 'GET',
               
crossDomain: true,
               
success: function () {
               
},
               
error: function () {
                   
alert('Failed!');
               
}
           
});
       
});
   
});
</script>


app.js

//safari workaround
app.use(function(req,res,next){
   
var safari = req.query.safari;
   
if(safari){
        req
.headers.cookie = safari;
   
}
   
next();
});

but when i make a redirect from editor.js to e.g. login.js the session-params are lost :-/
I've tried to pass the session-id before redirection but with no success.

var token = req.context.token;
res
.cookie('atlassian-addon-session', req.headers.cookie);
res
.redirect('/login?jwt=' + token + "&" + credentials + "&safari="+ encodeURIComponent(req.headers.cookie));

Also i've playing around with encodeURIComponent.

What i'm doing wrong.
How can i keep my session also when redirecting ?

Thank you
Lutz




James Hazelwood

unread,
Mar 5, 2017, 5:38:49 PM3/5/17
to Atlassian Connect Dev
Hi Lutz,

Perhaps you're seeing the same issue that's described here: https://github.com/expressjs/session/pull/69 - I just found this via google, perhaps you've seen it already.

It might also be worth taking a step back and asking whether you need to store things via cookies and sessions - what is it you are trying to store? If I recall correctly, you wanted to store credentials for a third-party system against a specific user. If you want to do this, all you need is to key off the client key and the user key (available via `context` in the JWT) - no sessions or cookies required.

Hope that helps,
James

lutz

unread,
Mar 6, 2017, 4:00:54 AM3/6/17
to Atlassian Connect Dev
Hi James

You are right.
Storing of user credential is one part of the app and does work without session and cookies... i only use a postgres-db and jugglingdb for ORM.
This part works fine.

The other part is that after the login to a 3rd party rest api, the logged on 3rd. party user receives some e.g. routing information, so it can be that each user has a different route to access endpoints of the 3rd party rest api. that the reason why i need sessions - i need to store this data temporary per logged in user. 
The add-on user can also make some selections of data which will be stored in the data-variable of the macro, these selection will be also stored in the session object.

Best Regards again
Lutz 

James Hazelwood

unread,
Mar 6, 2017, 5:14:17 AM3/6/17
to Atlassian Connect Dev
Ah, I see. How about the other part of the question? Does that workaround sound like something worth investigating?

lutz

unread,
Mar 6, 2017, 10:47:50 AM3/6/17
to Atlassian Connect Dev
I've tried to save the session with req.session.save before redirecting, but it has no effect. Every request using safari browser creates a new session with a other id.
Any further ideas how to adapt the AJS.conglomerate.cookie and simulate a true cookie ?

Regards

 
Reply all
Reply to author
Forward
0 new messages