如何在浏览器的 reddit api 中使用 oauth?

Posted

技术标签:

【中文标题】如何在浏览器的 reddit api 中使用 oauth?【英文标题】:How I do use oauth in the reddit api in browser? 【发布时间】:2020-05-11 00:48:20 【问题描述】:

我所做的一切都不起作用,而且我不断收到荒谬的 CORS 错误和其他问题。我只想做一个正常的誓言,通过浏览器登录用户。我想使用 snoowrap,但我什至无法使用它,因为我需要一个刷新令牌。

我已经授权该应用程序并从 API 取回“代码”,然后我应该通过向 https://www.reddit.com/api/v1/access_token 发出发布请求来使用它。

但我每次都会遇到 CORS 错误。

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).

代码:

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;

我什至不明白为什么有些东西会阻止我向公共 api 发出 POST 请求

【问题讨论】:

发布包含堆栈跟踪的完整错误消息会很有帮助 我不得不说,根据从 reddit 收到的响应,这看起来不像是公共 API 端点。我什至没有看到它列在api documentation for reddit 事实上,我只在 GitHub 上的 reddit-archive 上看到了这个端点。似乎您尝试与 Reddit API 交互的方式可能已经过时 是的,这就是我正在查看的页面,但我在其他任何地方都看不到,reddit 链接到他们的 api 页面和当前存储库上的那个页面 在哪里?我没有在任何地方看到链接,我通过谷歌搜索“reddit api access_token”到达那里 【参考方案1】:

经过数小时的搜索,我找到了解决方案:

如果您正在创建仅浏览器的 JS 应用(无服务器),您应该在 reddit console 中将您的应用类型选择为“已安装的应用”(而不是“网络应用”)。

然后您必须发送一个 Authorization 标头,其值为您的客户端 ID,如此处所述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,
  );

【讨论】:

以上是关于如何在浏览器的 reddit api 中使用 oauth?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 JSON 从 Reddit API 中提取 url 数据

如何在 JSON Schema 和 Open API (OAS) 中定义 UUID 属性

从 reddit api 获取 api oauth 访问令牌

如何处理android中reddit api的深层嵌套json响应?

从 Reddit 的 API 中检索评论

为啥我在尝试使用 reddit API 时会收到 405 错误?