【问题标题】:How to pass an Access Token from .NET (code behind) to Javascript如何将访问令牌从 .NET(隐藏代码)传递给 Javascript
【发布时间】:2018-09-02 11:36:37
【问题描述】:

我想通过 .NET 框架使用我自己的 API 密钥、秘密和刷新令牌“授权”,然后将 访问令牌 传递给 JavaScript,以便我可以将视频直接上传到 YouTube带有进度指示器。

我有working code via the .NET API,它将直接完成上传到我的频道[未经授权],但您没有收到进度指示(并且可能需要相当长的时间)并且文件必须先上传到我的服务器,然后再上传到YouTube 服务器。

服务器端访问代码与客户端访问代码不同吗?如果没有:

  1. 服务器端如何获取访问码?(获取字符串)
  2. ***如何通过 JavaScript 将其传递给 Google API? (不是如何写<%= access code %>,而是在哪里传递呢?)

我很清楚暴露访问令牌的安全风险,但这些确实会过期吗? (作为奖励,我怎样才能缩短过期时间)。这也是在受密码保护的网页内完成的,您不会获得“客户端密码”或“刷新令牌”

***更新 - 我想我找到了在 MediaUploader 对象中传递令牌的位置。

var uploader = new MediaUploader({
        baseUrl: 'https://www.googleapis.com/upload/youtube/v3/videos',
        file: selectedFile,
        token: token, // ***RIGHT HERE***
        metadata: metadata,
        params: params,
        onError: function(data) {

【问题讨论】:

标签: javascript c# .net youtube-api google-api-dotnet-client


【解决方案1】:

好的,经过数周的 API、.NET 和 JavaScript 文档研究后,我构建了以下解决方案....

按照YouTube V3 Developer documentation 设置您的所有密钥。 (选择 OAuth、Web 应用程序,并为您的 Javascript 和重定向代码输入 URI)

接下来使用OAuth Playground 获取您的刷新代码

一旦你有了你的 client_id、client_secret 和 refresh_token,你就准备好了!

此代码通过后面的代码进行简单的 HTTP/REST 调用,以获取有效期为 3600 秒(默认值)的 access_token。然后它将此字符串传递给 JavaScript 代码以供使用 ****WARNING****

这个使用任何 .NET 或 JavaScript 库,除了一个文件 cors_upload.js available on GitHub

唉,代码
默认.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="ApisCallTest.WebForm1" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <meta charset="utf-8" />
    <title>YouTube API Uploads via CORS</title>
    <style>
      #disclaimer {
        font-size: 0.75em;
        color: #aeaeae;
        max-width: 350px;
      }
      .during-upload { display: none; }
      label { display: block; }
      input[type="text"],
      textarea,
      progress {
        font-size: 16px;
        width: 15em;
        margin-bottom: 1em;
        padding: 0.5em;
        font-family: "Open Sans", sans-serif;
      }
    </style>
</head>
  <body>
    <div>
    <input input type="file" id="file" class="button" accept="video/*" />
    <button id="button">Upload Video</button>
    </div>
    <div class="during-upload">
    <p><span id="percent-transferred"></span>% done (<span id="bytes-transferred"></span>/<span id="total-bytes"></span> bytes)</p>
    <progress id="upload-progress" max="1" value="0"></progress>
    </div>
    <p id="disclaimer">By uploading a video, you certify that you own all rights to the content or that you are authorized by the owner to make the content publicly available on YouTube, and that it otherwise complies with the YouTube Terms of Service located at <a href="http://www.youtube.com/t/terms" target="_blank">http://www.youtube.com/t/terms</a></p>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    <script src="cors_upload.js"></script>
    <script>
      $('#button').on("click", goForUpload);
      function goForUpload() {
        if ($('#file').get(0).files[0]) {
          $('#button').attr('disabled', true);
          var uploadStartTime = 0;
          var metadata = {
            snippet: {
              title: 'PUT YOU TITLE HERE',
              description: 'THIS IS YOUR VIDEO DESCRIPTION',
              categoryId: '22'
            },
            status: {
              privacyStatus: 'unlisted'
            }
          };

          var uploader = new MediaUploader({
            baseUrl: 'https://www.googleapis.com/upload/youtube/v3/videos',
            file: $('#file').get(0).files[0],
            token: '<%= access_token %>',
            metadata: metadata,
            params: {
              part: Object.keys(metadata).join(',')
            },
            onError: function (data) {
              var message = data;
              // Assuming the error is raised by the YouTube API, data will be
              // a JSON string with error.message set. That may not be the
              // only time onError will be raised, though.
              try {
                var errorResponse = JSON.parse(data);
                message = errorResponse.error.message;
              } finally {
                alert(message);
              }
            },
            onProgress: function (data) {
              var currentTime = Date.now();
              var bytesUploaded = data.loaded;
              var totalBytes = data.total;
              // The times are in millis, so we need to divide by 1000 to get seconds.
              var bytesPerSecond = bytesUploaded / ((currentTime - this.uploadStartTime) / 1000);
              var estimatedSecondsRemaining = (totalBytes - bytesUploaded) / bytesPerSecond;
              var percentageComplete = (bytesUploaded * 100) / totalBytes;

              $('#upload-progress').attr({
                value: bytesUploaded,
                max: totalBytes
              });

              $('#percent-transferred').text(percentageComplete);
              $('#bytes-transferred').text(bytesUploaded);
              $('#total-bytes').text(totalBytes);

              $('.during-upload').show();
            },
            onComplete: function (data) {
              var uploadResponse = JSON.parse(data);
              alert('all done, you can store this id: ' + uploadResponse.id)
            }
          });
          uploadStartTime = Date.now();
          uploader.upload();
        }
      }
    </script>
  </body>
</html>

和 Default.aspx.cs

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;

namespace ApisCallTest
{
    public partial class WebForm1 : System.Web.UI.Page
    {
        private static readonly HttpClient client = new HttpClient();
        public string access_token;
        protected void Page_Load(object sender, EventArgs e)
        {
            var values = new Dictionary<string, string>
            {
               { "client_id", "REPLACE_ME" },
               { "client_secret", "REPLACE_ME" },
               { "refresh_token", "REPLACE_ME" },
               { "grant_type", "refresh_token" }
            };

            var content = new FormUrlEncodedContent(values);
            var response = client.PostAsync("https://www.googleapis.com/oauth2/v4/token", content);
            string json = response.Result.Content.ReadAsStringAsync().Result;
            dynamic obj = JObject.Parse(json);
            access_token = obj.access_token;
        }
    }
}

结果...从受密码保护的网页中,我可以让用户将视频上传到我的频道,不公开,并存储视频 ID,以便以后将该视频嵌入我的网站。

至于 ****WARNING****,这在某种程度上是一个安全问题,因为您正在(非常直接地)将您的个人访问密钥暴露给“公众”。它仅持续 1 小时,但将您使用的任何“访问范围”提供给“任何人”可用页面。

【讨论】:

  • 也许您应该考虑从后端而不是客户端上传。这是一些额外的工作量,但会将您的密钥保存在它所属的位置。
  • @Nikolaus 给我看一些带有进度指示的代码,我全力以赴!
  • 谢谢,这对我有帮助。谷歌自己的文档只是用所有的“帮助”库绝望地完成了。你真的只需要三个简单的 http 请求来上传视频。 “OAuth 游乐场”的诀窍是转到设置(齿轮图标),然后选中“使用您自己的 OAuth 凭据”。
猜你喜欢
  • 2010-10-21
  • 1970-01-01
  • 2017-04-09
  • 2018-03-13
  • 2019-03-30
  • 1970-01-01
  • 1970-01-01
  • 2017-01-16
  • 1970-01-01
相关资源
最近更新 更多