5

Nothing I do works, and I keep getting ridiculous CORS errors and other things. I just want to do a normal oath to log a user in, through the browser. I want to use snoowrap, but I can't even get far enough to use it, because i need a refresh token.

I already authorize the app and get the 'code' back from the API, which im then supposed to use by making a post request to https://www.reddit.com/api/v1/access_token.

But I just get CORS errors every time.

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://www.reddit.com/api/v1/access_token. (Reason: missing token ‘access-control-allow-headers’ in CORS header ‘Access-Control-Allow-Headers’ from CORS preflight channel).

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://www.reddit.com/api/v1/access_token. (Reason: CORS request did not succeed).

code:

const redirect_uri = 'https://EXAMPLE.com/reddit/';
const client_id = 'xxxxxxxxxxxxx';
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString); /*global URLSearchParams*/
const code = urlParams.get('code');

var snoowrap = window.snoowrap;






if (code) {
    console.log('code gotten', code);

    const data = {
        grant_type: 'authorization_code',
        code: code,
        redirect_uri: redirect_uri
    };

    ajax('https://www.reddit.com/api/v1/access_token', data, 'Basic client_id:', result => {
        console.log(result);

        const r = new snoowrap({
            userAgent: 'skeddit',
            clientId: client_id,
            clientSecret: 'fFP-6BKjFtvYpIkgFGww-c6tPkM',
            refreshToken: '',
        });

        r.getHot().map(post => post.title).then(console.log);
    });
}



//GET:  ajax(String url, Function success)
//POST: ajax(String url, Object postData, Function success)

function ajax(url, arg2, arg3, arg4) {
  if (typeof arg2 == 'function')
    var success = arg2;
  else {
    var postData = arg2;
    var headers = arg3;
    var success = arg4;
  }

  console.log('AJAX - STARTING REQUEST', url)

  //start new request
  var xhttp = new XMLHttpRequest({mozSystem: true});
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      success(JSON.parse(this.response));
      xhttp = null;
      console.log('AJAX - COMPLETE', this.response);
    }
  };

  if (postData) {
    //post request
    console.log('post data: ', postData);
    var formData = new FormData();

    for ( var key in postData ) {
      formData.append(key, postData[key]);
    }

    xhttp.open("POST", url, true); 
    xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    xhttp.setRequestHeader("Authorization", headers);
    xhttp.send(formData);
  }
  else {
    //get request
    xhttp.open("GET", url, true); 
    xhttp.send();
  }

  return xhttp;
}

I don't even understand why something would prevent me from doing a POST request to a public api

stackers
  • 2,701
  • 4
  • 34
  • 66
  • It would be helpful to post the full error message including the stack trace – gabriel.hayes Jan 24 '20 at 16:57
  • I have to say, based on the response received from reddit, this doesn't seem like a public API endpoint. I don't even see it listed in the [api documentation for reddit](https://www.reddit.com/dev/api/oauth) – gabriel.hayes Jan 24 '20 at 17:01
  • In fact, I only see this endpoint listed on the [`reddit-archive`](https://github.com/reddit-archive/reddit/wiki/oauth2) on GitHub. Seems like the way you are trying to interact with the Reddit API may be obsolete – gabriel.hayes Jan 24 '20 at 17:02
  • Yes that's the page I'm looking at, but I don't see anywhere else, and reddit links to that page on their api page and current repository – stackers Jan 24 '20 at 17:15
  • Where? I don't see a link there anywhere, I got there by googling "reddit api access_token" – gabriel.hayes Jan 24 '20 at 17:16
  • the OAuth2 links at the top of this page: https://github.com/reddit-archive/reddit/wiki/API – stackers Jan 24 '20 at 17:17
  • which i get to from clicking the API access rules at the top of this page https://www.reddit.com/dev/api/ – stackers Jan 24 '20 at 17:17
  • It also says on the archive page that it is subject to change without warning and that you should monitor [/r/redditdev](https://www.reddit.com/r/redditdev/). I'm 90% certain the reason this doesn't work is because this is a deprecated approach. ETA: Actually after perusing redditdev, it seems you may be right. Honestly, I'd look for an answer there, just search OAuth2 in redditdev to see what discussions come up and how other developers tackle the issue. – gabriel.hayes Jan 24 '20 at 17:19

1 Answers1

9

After hours of searching I found a solution:

If you're creating a browser-only JS app (no server), you should select your app type as "installed app" (instead of "web app") in the reddit console.

enter image description here

Then you have to send an Authorization header whose value is your Client Id, as stated here reddit/wiki/OAuth2

  const fd = new FormData();
  fd.append("code", code);
  fd.append("grant_type", "authorization_code");
  fd.append("redirect_uri", "your_redirect_uri");

  const r = await fetch("https://www.reddit.com/api/v1/access_token", {
    headers: {
      Authorization:
        "Basic " + btoa(unescape(encodeURIComponent(CLIENT_ID + ":" + ""))),
    },
    method: "POST",
    body: fd,
  });
LiamJC
  • 99
  • 1
  • 1
  • 11
Alireza Rezania
  • 106
  • 2
  • 4