Open bonnieli opened 3 years ago
Hi @bonnieli
Having some trouble getting calendar data to show even though I've included it in the scope in the passport.authentication
It's says that I'm missing an API Key as the error message when trying to access the calendar in the controller here: https://github.com/hatchways/team-vampire/compare/feature-be-google-calendar-freebusy-api
Surprisingly, I don't see a lot of passport related google calendar api authentication questions on stackoverflow.
I believe you're authenticating the user, before accessing the google endpoint to grab events but based on documentation you need to also pass in the access token again
https://stackoverflow.com/questions/46173620/authenticating-googleapi-node-library-with-passport
you're missing the auth: oauth2Client
part
I believe you're authenticating the user, before accessing the google endpoint to grab events but based on documentation you need to also pass in the access token again
https://stackoverflow.com/questions/46173620/authenticating-googleapi-node-library-with-passport
you're missing the
auth: oauth2Client
part
Hi @bonnieli, so I'm guessing I need to store the refresh_token and access_token that gets passed in the parameters in the passport google oauth2 strategy in order to set the oauth2 credentials like this:
module.exports = function(passport) {
// console.log(process.env.GOOGLE_CLIENT_ID);
passport.use(new GoogleStrategy({
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: "/api/auth/google/callback"
},
async (accessToken, refreshToken, profile, done) => {
const newUser = {
accessToken: accessToken, // <---
refreshToken: refreshToken, // <---
googleId: profile.id,
firstName: profile.name.givenName,
lastName: profile.name.familyName,
email: profile.emails[0].value,
profilePicture: profile.photos[0].value
};
Currently, my User schema doesn't have keys for access tokens and refresh tokens so I guess I'll add those in, delete the user, and create a new user to assign it access and refresh tokens upon authentication.
hi @bonnieli , just to let you know I was able to access my google calendar following that stack overflow post with the access and refresh tokens I've added to the User model after initial authentication. Thanks, again!
Updated code pushed to the branch: https://github.com/hatchways/team-vampire/compare/feature-be-google-calendar-freebusy-api
@bonnieli Was able to test the freebusy query on my calendar which returned an array of start/end times that correspond to events in my calendar. Will figure out how to get the free time slots on my calendar using this array by, I'm guessing, subtracting the "busy" end and start times and storing the "free" start and end times in a new array.
I also ran into another issue that had my stored access and refresh tokens becoming invalid which caused the oauth2 credentials to become invalid for accessing the calendar that I "fixed" by updating the tokens during the authentication process. Can you check if this method makes sense in my code?
hm did your access/refresh tokens change in any way when you call this new controller?
let's walk through this later today
hi @bonnieli I'm getting an error after being logged in for a long amount of time when I try to access the google calendar api:
{ GaxiosError: invalid_request
at Gaxios.<anonymous> (/home/michael/Documents/webdev/projects/team-vampire/server/node_modules/gaxios/build/src/gaxios.js:73:27)
at Generator.next (<anonymous>)
at fulfilled (/home/michael/Documents/webdev/projects/team-vampire/server/node_modules/gaxios/build/src/gaxios.js:16:58)
at processTicksAndRejections (internal/process/task_queues.js:86:5)
response:
{ config:
{ method: 'POST',
url: 'https://oauth2.googleapis.com/token',
data:
'refresh_token=1%2F%2F0fCxrnJByRJNjCgYIARAAGA8SNwF-L9Irl-0_dgDK4Wq9l4fW5xbWIaDldMH4KwQfk9c66S5Ufwj6gmB4vgaA34yEiLXmR3Qy8Q4&client_id=&client_secret=cRH2vVlg-jcdto68q-Wr8Y9s&grant_type=refresh_token',
headers: [Object],
params: [Object: null prototype] {},
paramsSerializer: [Function: paramsSerializer],
body:
'refresh_token=1%2F%2F0fCxrnJByRJNjCgYIARAAGA8SNwF-L9Irl-0_dgDK4Wq9l4fW5xbWIaDldMH4KwQfk9c66S5Ufwj6gmB4vgaA34yEiLXmR3Qy8Q4&client_id=&client_secret=cRH2vVlg-jcdto68q-Wr8Y9s&grant_type=refresh_token',
validateStatus: [Function: validateStatus],
responseType: 'json' },
data:
{ error: 'invalid_request',
error_description: 'Could not determine client ID from request.' },
headers:
{ 'alt-svc':
'h3-29=":443"; ma=2592000,h3-T051=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"',
'cache-control': 'no-cache, no-store, max-age=0, must-revalidate',
connection: 'close',
'content-encoding': 'gzip',
'content-type': 'application/json; charset=utf-8',
date: 'Thu, 10 Dec 2020 00:37:50 GMT',
expires: 'Mon, 01 Jan 1990 00:00:00 GMT',
pragma: 'no-cache',
server: 'scaffolding on HTTPServer2',
'transfer-encoding': 'chunked',
vary: 'Origin, X-Origin, Referer',
'x-content-type-options': 'nosniff',
'x-frame-options': 'SAMEORIGIN',
'x-xss-protection': '0' },
status: 400,
statusText: 'Bad Request' },
config:
{ method: 'POST',
url: 'https://oauth2.googleapis.com/token',
data:
'refresh_token=1%2F%2F0fCxrnJByRJNjCgYIARAAGA8SNwF-L9Irl-0_dgDK4Wq9l4fW5xbWIaDldMH4KwQfk9c66S5Ufwj6gmB4vgaA34yEiLXmR3Qy8Q4&client_id=&client_secret=cRH2vVlg-jcdto68q-Wr8Y9s&grant_type=refresh_token',
headers:
{ 'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent': 'google-api-nodejs-client/3.1.2',
Accept: 'application/json' },
params: [Object: null prototype] {},
paramsSerializer: [Function: paramsSerializer],
body:
'refresh_token=1%2F%2F0fCxrnJByRJNjCgYIARAAGA8SNwF-L9Irl-0_dgDK4Wq9l4fW5xbWIaDldMH4KwQfk9c66S5Ufwj6gmB4vgaA34yEiLXmR3Qy8Q4&client_id=&client_secret=cRH2vVlg-jcdto68q-Wr8Y9s&grant_type=refresh_token',
validateStatus: [Function: validateStatus],
responseType: 'json' },
code: '400' }
I think this is trying to get new tokens to access the api.
The only way I have right now to fix this is to do the authentication process again going through the correct controller, but I know in the office hours you mentioned the need to get new tokens because they expire which is what the google calendar api mentions as well.
hm did you change anything in the backend code? based off of that error message:
{ error: 'invalid_request',
error_description: 'Could not determine client ID from request.' },
for some reason client Id isn't being passed in?
@bonnieli no, I didn't change anything in the back-end. that error message didn't come up again when I accessed the auth/google controller which created exported a new google oauth2 passport strategy and set new access and refresh tokens.
it may be the access token has expired. perhaps the 400 error is because of that although the error message is quite confusing but may be designed that way for security purposes
if you can detect that 400 error maybe we'll need to do a refresh of the token on check
Create a route that:
Google Calendar API
Each date you select, it’ll load the appointment slots available
[ {start_time: 2323234, end_time: 234234}, {start_time: 2323234, end_time: 234234}, {start_time: 2323234, end_time: 234234}, ... ]