Search code examples
javascriptauthenticationgreasemonkeymendeley

How to programmatically open login window using GreaseMonkey userscript for implicit grant authorization


How do I code my GreaseMonkey userscript to take me to an authorization/login window while on a different website (www.sharelatex.com)? My understanding was that GM_xmlhttpRequest would perform this function, and while I get an "OK" status after GM_xmlhttpRequest has successfully loaded, no login window presents itself. Should I be using a different function? This login must be done programmatically so that the userscript can "catch" the token number that gets attached to the redirect URL following successful login. This token number will then be used in a Mendeley API call to download the desired file from my Mendeley account (using implicit grant flow).

Background info: I am trying to build a GreaseMonkey userscript that will add a button to my www.sharelatex.com account that, when pushed, will automatically download a file from my account on www.mendeley.com using that site's API. The code associated with the button should also take of login and authentication requirements needed to use the API. I've registered my application with Mendeley, received a "client ID" number (0000, for purposes of illustration) which I have used to construct the following url:

var urlAuth  = "https://api.mendeley.com/oauth/authorize?client_id=0000&redirect_uri=http://localhost&response_type=token&scope=all"

If I manually enter the above URL directly into my browser as a URL address, I am taken to a login/authorization page that looks like the below, which is exactly what I want to see, but programmatically instead of manually: Click here to view authentication/login window Below are the relevant bits of my malfunctioning GreaseMonkey userscript:

// ==UserScript==
//  ... skipping over irrelevant lines ... 
// @grant       GM_xmlhttpRequest
// ==/UserScript==
var urlAuth  = "https://api.mendeley.com/oauth/authorize?client_id=0000&redirect_uri=http://localhost&response_type=token&scope=all"
/* ***************   CREATE BUTTON ************************* */
var input = document.createElement("input"); 
input.type = "button"; 
input.value="Update bibtex"; 
input.onclick = getBib; 
input.setAttribute("style", "font-size:18px; position:absolute; bottom:10px;left:10px;");
document.body.appendChild(input);
/* ================================================================ */
function getBib()
{    
GM_xmlhttpRequest({ 
method: 'GET',
url: urlAuth, 
onload: function(reply) { alert(reply.statusText) }
}

the Alert indicates an OK status, but no login window presents itself. When I do an:

alert(urlAuth)

within the onload section and I manually copy/paste what appears in the alert box into the browser address area, the browser takes me to the appropriate login/authorization window, so the URL itself is fine.

Why isn't the GM_xmlhttpRequest taking me to the login screen? Am I misunderstanding the functionality of GM_xmlhttpRequest, and should instead be using a different function? I've spent about 2 solid months trying to figure this out, poring through hundreds of references on the topic of OAuth2, userscripts, Mendeley API, etc. A few examples: http://userscripts-mirror.org/scripts/review/292038 (was promising as it is the only GreaseMonkey/Mendeley userscript out there but unfortunately does not perform OAuth2 stuff), https://salesforce.stackexchange.com/questions/76397/accessing-salesforce-rest-api-through-greasemonkey-script (the provided answer never addressed the question of how to get the login window).


Solution

  • While the topic of OAuth2 process involves multiple steps, this question was focused on one step: how to get the authorization / log-in window to present itself through a GreaseMonkey userscript. The answer (see comment by Brock Adams above) is given by an example provided in meta.stackexchange.com/a/293498/148310. More specifically, the log-in window is produced by the window.open function, as illustrated in the following example (see Line #21 below):

    // ==UserScript==
    <other needed info in the metadata block should be included here>
    // @match       https://stackexchange.com/oauth/login_success*
    // ==/UserScript==
    
    var rootUrl = "https://api.mendeley.com/oauth/authorize?"
    // the rootUrl should point to whatever API service you are trying to use. 
    // I am using Mendeley, but could be i.e, facebook, YouTube, Twitter, Google, etc. 
    var clientId = "0000"   // needs to be the number you got when you registered your app
    // through whatever API service you want to use
    var redirectUrl = "https://stackexchange.com/oauth/login_success"  
    // The above directs where the login page will be redirected after successful
    //     log-in/authorization. 
    // This URL needs to point to a real page. 
    // Also make sure that whatever is given for the redirectUrl is also 
    //     listed in the @match statement in the metadata block section at the top, 
    //     but with an astericks at the end (to allow for the token number to be 
    //     attached as a hash fragment, as part of the OAuth2 process)
    var other   = "response_type=token&scope=all" 
    var urlAuth = rootUrl + clientId + "&" + redirectUrl + "&" + other
    authWindow = window.open ( urlAuth, "Log in", "resizeable, scrollbars, status, toolbar, 
                 dependent, width=660,height=480" ) 
    // tailor window sizing, etc. to your own aesthetics