Hi, I'm trying to get the image file data (not just the URL) for a member's avatar. The URL returned the a user's avatarUrls along the lines of:
The CDN returns a 302 redirect back to our Atlassian site along the lines of:
The problem I'm running into is that the call to mydomain.atlassian.net needs to be authenticated, and I don't know how to do that via the API, without using cookies, which the API documentation recommends we avoid. So... what am I missing here?
Hi, here's what I got to work for our cloud account
Here is some TypeScript that demonstrates a class that handles the authentication and redirect required to get Avatar URLs...
import * as request from "request-promise-native";
export interface IAtlassianSiteProxy {
retrieveImage(url: string): Promise<IAtlassianAvatar>;
}
export interface IAtlassianAvatar {
readonly data: Buffer;
readonly contentType: string;
}
export class AtlassianSiteProxy implements IAtlassianSiteProxy {
private _atlassianDomain: string;
private _userName: string;
private _password: string;
private _apiUserName: string;
private _apiKey: string;
private _cookie: string = '';
public constructor(atlassianDomain: string, userName: string, password: string, apiUserName: string, apiKey: string) {
this._atlassianDomain = atlassianDomain;
this._userName = userName;
this._password = password;
this._apiUserName = apiUserName;
this._apiKey = apiKey;
}
/**
* Launch session to get cookie value
*/
private async getAtlassianCookie(): Promise<string> {
if (this._cookie) {
return this._cookie;
}
var options = {
uri: this._atlassianDomain + '/rest/auth/1/session',
method: 'POST',
headers: {
"Accept": "application/json",
"Content-type": "application/json"
},
auth: {
'user': this._apiUserName,
'pass': this._apiKey
},
body: {
username: this._userName,
password: this._password
},
json: true,
resolveWithFullResponse: true,
followRedirect: true,
followAllRedirects: true
};
let response = await request(options);
let headers = response.headers;
/* Flatten out cookies into a single string */
if (headers['set-cookie']) {
this._cookie = headers['set-cookie'].map(function (cookie: string) {
let i = cookie.indexOf(';');
let j = cookie.indexOf('=');
if (i > j && i > -1) {
let name = cookie.substr(0, j);
let value = cookie.substr(j + 1, i - j - 1);
return name + '=' + value;
} else {
return '';
}
}).join('; ').toString();
return this._cookie;
}
throw "Cookies not received from Atlassian session";
}
/**
* Retrieve the image specified by the URL, handling authentication and redirects
* @param url
*/
public async retrieveImage(url: string): Promise<IAtlassianAvatar> {
let cookie = await this.getAtlassianCookie();
let avatarOptions = {
method: 'GET',
uri: url,
headers: {
Connection: 'keep-alive',
Cookie: cookie
},
auth: {
'user': this._userName,
'pass': this._apiKey
},
encoding: null,
resolveWithFullResponse: true,
followRedirect: true
};
let response = await request(avatarOptions);
let contentType = response.headers['content-type'];
let data = response.body;
return {
contentType: contentType,
data: data
};
}
}
Hi @Thomas Deiler, I tried adding your suggested headers, to no avail. I suspect the problem is that the second URL, to get the avatar file, is not an API call, but a site call. Somehow, I have to get the cookies required to access the site, not just the API.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I reproduced your problems in my environment - I'll come back when I solved it.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi, first - thanks again for taking the time to look into this. I ran wget on my machine and ended up getting the "generic" icon.
The cookie file from wget looks like this:
````
.atlassian.com TRUE / TRUE 0 cloud.session.token deleted
id.atlassian.com FALSE / FALSE 0 atlassian.account.ffs.id (UUID)
.id.atlassian.com TRUE / TRUE 0 cloud.session.token deleted
id.atlassian.com FALSE / TRUE 0 atlassian.account.xsrf.token (HexOrBinStringLookingValue)
````
When I browse to the secure/useravatar in Jira (and we're using the hosted version, probably should have said that explicitly) and look at the cookies going over, there are a lot more cookies getting sent:
_utma, _utmz, ajx_user_id, ajs_group_id, ajs_anonymous_id, atlassian.xsrf.token, _utmb, &tmc, &tmt, cloud.session.token, _csrf
The interesting one to me is cloud.session.token, where wget was setting that as "deleted", whereas when hitting the Atlassian site in the browser it is a big long value.
I guess the next thing I'll try is injecting the cookeis in manually until I figure out which one/s are really required...
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Dear @Jason Terando,
that sounds fine. Was my answer fine enough to be accepted?
Many thanks in advance
Thomas
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Dear @Jason Terando,
you have to do basic authentication (normally) and add a custom header (Content-Type: application/json), first. Then
GET /api/2/issue/<issue key>
should work.
For some API functions, it only works when adding additional headers:
accept: application/json
X-Atlassian-Token: nocheck
So long
Thomas
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Dear @Jason Terando
Ok - got it. My solution is with wget, but this can be for sure adapted to any other program (like curl) or programming language.
I have looked at the source code of the login page of Jira. Username and password are stored in variables os_username and os_password. Additionally the 'save login on my computer' has to be checked. This is the variable os_cookie.
wget -d --save-cookies cookies.txt --keep-session-cookie --post-data 'os_username=admin&os_password=admin&os_cookie=true' http://localhost:8080/login.jsp -O login-result.html
This will authorize you, session saved to cookie.
wget -d --load-cookies cookies.txt http://localhost:8080/secure/useravatar?size=medium&avatarId=10122 -O avatar.png
This will download one avatar, taking the session from before. The '-d' option delivers more output, to see the HTTP header information.
Tell me, if you could reproduce what I found out.
So long
Thomas
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Online forums and learning are now in one easy-to-use experience.
By continuing, you accept the updated Community Terms of Use and acknowledge the Privacy Policy. Your public name, photo, and achievements may be publicly visible and available in search engines.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.