使用现有凭据向 youtube 数据 api 发出请求

Posted

技术标签:

【中文标题】使用现有凭据向 youtube 数据 api 发出请求【英文标题】:Making request to youtube data api with already existing credentials 【发布时间】:2017-11-20 21:26:34 【问题描述】:

我正在尝试向 youtube 数据 API 发出授权请求,以获取有关用户活动和订阅的信息。在我的应用程序中,我使用passportjs 和passport-youtube-v3 strategy 执行授权流程。出于这个原因,我已经拥有访问用户数据所需的授权令牌。对我来说,如果我已经拥有用户凭据,我还不清楚应该如何使用 youtube API。这是我的流程和我挣扎的地方:

    使用 passportjs 获取用户凭据(令牌)。

    使用 axios 或任何其他请求库向 youtube 数据 API 发出“手动”请求:

    const baseUri = "https://www.googleapis.com/youtube/v3/subscriptions";
    const opts = 
      params: 
        part: "snippet",
        mine: true,
        fields: "items(snippet(title%2C+channelId%2Cthumbnails%2Fdefault%2Furl))",
        key: youtubeAuth.clientID,
        access_token: user.youtube.token
      
    
    
    return axios.get(baseUri, opts)
      .then(response => 
        console.log(response);
      )
      .catch(err => 
        console.log(err);
      );
    

我的关键参数看起来像这样:

857220510254-q8pkdd9ugp2be167s5ged7ave4pqa5rn.apps.googleusercontent.com

令牌看起来像这样

ya29.GlttZIaiVLxzaZDu-5-KTd5jRHhqh684Q4PFoUF3_72D9Ig0uz9CyrLwnotKMOUcnZ93kTVoYH5Bc6WCfUS1tNY5DbEMDN7nCeiUMU9vmkQWLTUAaKVS3A7XhB65

这似乎不是正确的做法,因为我不断收到 401 错误:


    "error": 
        "errors": [
            
                "domain": "global",
                "reason": "authError",
                "message": "Invalid Credentials",
                "locationType": "header",
                "location": "Authorization"
            
        ],
        "code": 401,
        "message": "Invalid Credentials"
    

是否可以这样做,或者我必须使用nodejs quickstart example中所示的google SDK?

【问题讨论】:

【参考方案1】:

要进行 Google API 调用,推荐的方法是使用 Google 官方库:Google APIs Node.js Client。

您可以通过以下方式申请 Youtube 订阅:

var google = require('googleapis'),
    OAuth2 = google.auth.OAuth2;

// ....

var oauth2Client = new OAuth2(
    config.clientID,
    config.clientSecret,
    config.callbackURL
);

oauth2Client.credentials = 
    access_token: req.user.access_token,
    refresh_token: req.user.refresh_token
;

var youtube = google.youtube(
    version: 'v3',
    auth: oauth2Client
);

youtube.subscriptions.list(
    part: 'snippet',
    mine: true,
    headers: 
, function(err, data, response) 
    console.log(data);
);

这是使用passport-youtube-v3googleapismongoose的完整示例:

var app = require('express')(),
    passport = require('passport'),
    YoutubeV3Strategy = require('passport-youtube-v3').Strategy,
    mongoose = require('mongoose'),
    google = require('googleapis'),
    OAuth2 = google.auth.OAuth2,
    session = require('express-session');

var config = 
    clientID: 'CLIENT_ID',
    clientSecret: 'CLIENT_SECRET',
    callbackURL: 'http://localhost:8080/auth/google/callback'
;

var db = mongoose.connect("mongodb://localhost:27017/testDB");

var userSchema = new mongoose.Schema(
    _id:  type: String, unique: true ,
    access_token: String,
    refresh_token: String,
    name: String
,  collection: "user" );

var User = db.model('User', userSchema);

passport.serializeUser(function(user, done) 
    done(null, user._id);
);

passport.deserializeUser(function(id, done) 
    User.findById(id, function(err, user) 
        done(err, user);
    );
);

passport.use(new YoutubeV3Strategy(
        clientID: config.clientID,
        clientSecret: config.clientSecret,
        callbackURL: config.callbackURL,
        scope: ['https://www.googleapis.com/auth/youtube.readonly']
    ,
    function(accessToken, refreshToken, profile, done) 

        process.nextTick(function() 

            User.findOne( _id: profile.id , function(err, res) 
                if (err)
                    return done(err);
                if (res) 
                    console.log("user exists");
                    return done(null, res);
                 else 
                    console.log("insert user");
                    var user = new User(
                        _id: profile.id,
                        access_token: accessToken,
                        refresh_token: refreshToken,
                        name: profile.displayName
                    );
                    user.save(function(err) 
                        if (err)
                            return done(err);
                        return done(null, user);
                    );
                
            )
        );
    
));

function userLogged(req, res, next) 
    if (req.isAuthenticated())
        return next();
    res.redirect('/auth/google');


app.use(session( secret: 'somesecret' ));
app.use(passport.initialize());
app.use(passport.session());

app.get('/auth/google', passport.authenticate('youtube'));

app.get('/auth/google/callback',
    passport.authenticate('youtube', 
        successRedirect: '/profile',
        failureRedirect: '/'
    ));

app.get('/profile', userLogged, function(req, res) 

    var oauth2Client = new OAuth2(
        config.clientID,
        config.clientSecret,
        config.callbackURL
    );

    oauth2Client.credentials = 
        access_token: req.user.access_token,
        refresh_token: req.user.refresh_token
    ;

    google.youtube(
        version: 'v3',
        auth: oauth2Client
    ).subscriptions.list(
        part: 'snippet',
        mine: true,
        headers: 
    , function(err, data, response) 
        if (err) 
            console.error('Error: ' + err);
            res.json(
                status: "error"
            );
        
        if (data) 
            console.log(data);
            res.json(
                status: "ok",
                data: data
            );
        
        if (response) 
            console.log('Status code: ' + response.statusCode);
        
    );
);

app.listen(8080)

console.log('go to http://localhost:8080/auth/google')

要运行此示例,您应该在 google 控制台中:

javascript 来源:http://localhost:8080 重定向 URI:http://localhost:8080/auth/google/callback

请注意,您也可以使用passport-google-oauth 代替passport-youtube-v3

【讨论】:

以上是关于使用现有凭据向 youtube 数据 api 发出请求的主要内容,如果未能解决你的问题,请参考以下文章

重复使用 Oauth2 凭据来访问 YouTube api [关闭]

来自 Youtube API 的 OAUTH 凭据无效

YouTube API v3无法正常使用[重复]

如何从`getStaticProps`向API路由发出请求

如何在现有iframe上使用YouTube API?

带有 API v3 的 Youtube 视频标题没有 API 密钥?