YouTube 数据 API 检索用户频道 ID 时出现问题
Problem with YouTube Data API to retrieve user's channel Id
我正在尝试实现一个 React - Node js 应用程序,该应用程序使用 Google 对用户进行身份验证,然后使用 google api 检索其 YouTube 频道 ID。我是 Google APIs 的新手,所以我需要一些帮助才能使此代码正常工作。 Google 的身份验证非常有效,但我在发出检索频道 ID 的请求时遇到了很多困难。
这是用react-google-login实现的React认证组件中要关注的代码:
<GoogleLogin
clientId={process.env.REACT_APP_GOOGLE_CLIENT_ID}
buttonText="Log in with Google"
onSuccess={handleGoogleLoginSuccess}
onFailure={handleGoogleLoginFailure}
cookiePolicy={'single_host_origin'}
scope='https://www.googleapis.com/auth/youtube.readonly'
/>
const handleGoogleLoginSuccess = (googleData) => {
//The token id is in googleData.tokenId
console.log(googleData);
axios.post('auth/googleLogin', {
token: googleData.tokenId,
access_token: googleData.accessToken
}).then(response => {
//Login success
if(response.data.loginStatus === 'ok') {
setLoginMessage(''); //Reset message
const user = response.data.user;
console.log(user.email + " " + user.firstName + " " + user.lastName)
registerUser(user); //Register user in the context
//console.log(currentUser.email + " " + currentUser.firstName + " " + currentUser.lastName)
localStorage.setItem('user', JSON.stringify(user)); //Push user in the storage
history.push('/home'); //Redirect to home page
}else{ //Login fail
//Set error messages.
const message = response.data.message;
setLoginMessage(message);
}
});
}
const handleGoogleLoginFailure = () => {
setLoginMessage("Impossible to login with Google at the moment. Please retry later.")
}
而快递服务器的终点是:
router.post('/googleLogin', async (req, res) => {
const { token, accessToken } = req.body;
const ticket = await client.verifyIdToken({
idToken: token,
audience: process.env.CLIENT_ID
});
const {email, given_name, family_name} = ticket.getPayload();
const { OAuth2 } = google.auth;
const oauth2Client = new OAuth2();
oauth2Client.setCredentials({ access_token: accessToken });
var service = google.youtube({
version: 'v3',
auth: oauth2Client,
});
service.channels.list({
key: process.env.GOOGLE_API_KEY,
auth: client,
mine: true,
part: 'snippet',
}, (err, response) => {
if(err) {
console.log(err);
return;
}
var channels = response.data.items;
console.log(channels);
});
const [user, created] = await User.upsert({
email: email,
firstName: given_name,
lastName: family_name,
youtubeChannelId: 'TODO'
});
if(user) {
const accessToken = createTokens(user);
res.cookie("access-token", accessToken, {
maxAge: 60 * 60 * 24 * 1000, //one day
httpOnly: true
});
return res.json({
loginStatus: 'ok',
user: user
});
}else{
console.log("Error in login with Google");
}
});
我遇到错误:
错误:未设置访问权限、刷新令牌、API 密钥或刷新处理程序回调。
一些想法?
如果您使用 Google OAuth 2.0 流程,我不确定您为什么使用 API 密钥,因为您发送的是用于识别身份的用户访问令牌使用您的客户端 ID 完成 OAuth 流程的用户。
此外,我建议使用全局服务身份验证,这样您就不需要向每个服务调用发送身份验证凭据。
List my YouTube channels
View in Fusebit
const { OAuth2 } = google.auth;
const oauth2Client = new OAuth2();
oauth2Client.setCredentials({ access_token: accessToken });
// Add global service auth
google.options({ auth: oauth2Client });
const youtube = googleClient.youtube('v3');
const channelsResponse = await youtube.channels.list({
part: 'id,statistics,snippet',
mine: true
});
我正在尝试实现一个 React - Node js 应用程序,该应用程序使用 Google 对用户进行身份验证,然后使用 google api 检索其 YouTube 频道 ID。我是 Google APIs 的新手,所以我需要一些帮助才能使此代码正常工作。 Google 的身份验证非常有效,但我在发出检索频道 ID 的请求时遇到了很多困难。
这是用react-google-login实现的React认证组件中要关注的代码:
<GoogleLogin
clientId={process.env.REACT_APP_GOOGLE_CLIENT_ID}
buttonText="Log in with Google"
onSuccess={handleGoogleLoginSuccess}
onFailure={handleGoogleLoginFailure}
cookiePolicy={'single_host_origin'}
scope='https://www.googleapis.com/auth/youtube.readonly'
/>
const handleGoogleLoginSuccess = (googleData) => {
//The token id is in googleData.tokenId
console.log(googleData);
axios.post('auth/googleLogin', {
token: googleData.tokenId,
access_token: googleData.accessToken
}).then(response => {
//Login success
if(response.data.loginStatus === 'ok') {
setLoginMessage(''); //Reset message
const user = response.data.user;
console.log(user.email + " " + user.firstName + " " + user.lastName)
registerUser(user); //Register user in the context
//console.log(currentUser.email + " " + currentUser.firstName + " " + currentUser.lastName)
localStorage.setItem('user', JSON.stringify(user)); //Push user in the storage
history.push('/home'); //Redirect to home page
}else{ //Login fail
//Set error messages.
const message = response.data.message;
setLoginMessage(message);
}
});
}
const handleGoogleLoginFailure = () => {
setLoginMessage("Impossible to login with Google at the moment. Please retry later.")
}
而快递服务器的终点是:
router.post('/googleLogin', async (req, res) => {
const { token, accessToken } = req.body;
const ticket = await client.verifyIdToken({
idToken: token,
audience: process.env.CLIENT_ID
});
const {email, given_name, family_name} = ticket.getPayload();
const { OAuth2 } = google.auth;
const oauth2Client = new OAuth2();
oauth2Client.setCredentials({ access_token: accessToken });
var service = google.youtube({
version: 'v3',
auth: oauth2Client,
});
service.channels.list({
key: process.env.GOOGLE_API_KEY,
auth: client,
mine: true,
part: 'snippet',
}, (err, response) => {
if(err) {
console.log(err);
return;
}
var channels = response.data.items;
console.log(channels);
});
const [user, created] = await User.upsert({
email: email,
firstName: given_name,
lastName: family_name,
youtubeChannelId: 'TODO'
});
if(user) {
const accessToken = createTokens(user);
res.cookie("access-token", accessToken, {
maxAge: 60 * 60 * 24 * 1000, //one day
httpOnly: true
});
return res.json({
loginStatus: 'ok',
user: user
});
}else{
console.log("Error in login with Google");
}
});
我遇到错误: 错误:未设置访问权限、刷新令牌、API 密钥或刷新处理程序回调。
一些想法?
如果您使用 Google OAuth 2.0 流程,我不确定您为什么使用 API 密钥,因为您发送的是用于识别身份的用户访问令牌使用您的客户端 ID 完成 OAuth 流程的用户。
此外,我建议使用全局服务身份验证,这样您就不需要向每个服务调用发送身份验证凭据。
List my YouTube channels | View in Fusebit |
---|
const { OAuth2 } = google.auth;
const oauth2Client = new OAuth2();
oauth2Client.setCredentials({ access_token: accessToken });
// Add global service auth
google.options({ auth: oauth2Client });
const youtube = googleClient.youtube('v3');
const channelsResponse = await youtube.channels.list({
part: 'id,statistics,snippet',
mine: true
});