Hi,
I want to be able to use google-apis after my OAuth authentication. How can I achieve this with
payload-plugin-oauthThanks
GET accessToken with payload-plugin-oauth
Which API's do you want to connect with? In my experience with Googlemaps for example I don't authorize with my Google account, but with some sort of authentication token that I need to provide in my requests via the Headers or url
Hi 👋 , Thank you for the response.
I would like to obtain an access token to access Google Calendar, as shown below
I would like to be able to insert events into my customer's calendar using the previous OAuth , if its make sens and if its possible
But whenever I see OAuth use cases in PayloadCMS, it's just to verify the user's identity without using the access token afterward to work with the "user's APIs" as google calendar.
maybe i need to store accessToken/refreshToken in Redis or my main database during Passport strategy
const strategy = new OAuth2Strategy(options, async function (...but idk if it is the right way to do it
Well, since Payload's authentication method is meant for authorizing users to gain access to Payload, I don't think that you'd want to take this route.
I've never used the OAuth2Strategy method, but [their documentation](
https://developers.google.com/identity/protocols/oauth2/web-server) on how to do this is quite extensive. It sure is a long read, but in the end you'd like to end up with something like this:
const {google} = require('googleapis');
const crypto = require('crypto');
const express = require('express');
const session = require('express-session');
/**
* To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI
* from the client_secret.json file. To get these credentials for your application, visit
* https://console.cloud.google.com/apis/credentials.
*/
const oauth2Client = new google.auth.OAuth2(
YOUR_CLIENT_ID,
YOUR_CLIENT_SECRET,
YOUR_REDIRECT_URL
);
// Access scopes for read-only Drive activity.
const scopes = [
'https://www.googleapis.com/auth/drive.metadata.readonly'
];
// Generate a secure random state value.
const state = crypto.randomBytes(32).toString('hex');
// Store state in the session
req.session.state = state;
// Generate a url that asks permissions for the Drive activity scope
const authorizationUrl = oauth2Client.generateAuthUrl({
// 'online' (default) or 'offline' (gets refresh_token)
access_type: 'offline',
/** Pass in the scopes array defined above.
* Alternatively, if only one scope is needed, you can pass a scope URL as a string */
scope: scopes,
// Enable incremental authorization. Recommended as a best practice.
include_granted_scopes: true,
// Include the state parameter to reduce the risk of CSRF attacks.
state: state
});Which is just a copy of [step 1](
https://developers.google.com/identity/protocols/oauth2/web-server#creatingclient) of their implementation guide btw
So I need to ask my customer twice if they trust the application to perform actions on their Google account (first time asking for the auth token and second time asking for access to the calendar).
I believe that what is described in this document is the same thing that happens in the background within the plugin. but i'm maybe wrong
Yes.
If you wouldn't ask the user twice, it would imply that whenever you have someone authorized via Google. You could use their against against any of their API's.
Allowing you to develop an application that access the calendar, while in the background making a copy of all my e-mails 😅
I believe there is an obligation to provide a list of scopes to specify which APIs the 'contract' allows read/write access to, in order to avoid giving full access (in my case, I only need access to the calendar).
That's why I find it strange to ask multiple times for simple things like granting access to the calendar or basic user info for an application like mine, which is basically a scheduler. So I need to find a proper way to do it just once during the payload OAuth process, if possible of course.
But you’re right, I’ll ask more people what they think about single authorization vs multiple authorizations. Thank you very much for pointing that out to me.
It's a UX problem, but it is actually a really common pattern
Last time I used it as to transform my Spotify playlists to deezer. First I got an authorization page for Spotify, than I get a page with an overview like "Deezer wants to get access to X,Y,Z". Which I than can authorize or not. I'm thinking of a comparable tool that is dependent on Google, but can't think of one this quick
Yes, you are right, but in this case, my application cannot function without Google Calendar, so asking for access all at once is not a bad idea in my opinion. As you mentioned, it's a UX issue, so I'll ask them again if they are okay with it. For now, I'd like to proceed with this plugin as I mentioned earlier ☀️
Do I need to store tokens in raw form or should they be encrypted? If encryption is required, how can I achieve this? For example, the code found here link does not seem suited for my case.
https://github.com/payloadcms/payload/blob/39e110e6331efff0ca8ca7174780076243a016de/packages/payload/src/auth/strategies/local/generatePasswordSaltHash.ts#L33The harder you make it for others to make use of your data, the better. That being said, you won't expose the key to the public - since you'll be using it in a background process - you have the opportunity to de-activate the key whenever you like,
plusyou can configure it in Google to be only accessible from a specific domain.
So whenever you have figured that someone has acquired an API token (of which you want to limit what you can do with it to as few features as possible), he can only get data from the Google API when he can create files that are being processed by your server.
The idea behind tokens is that they grant limited access with a limited shelf live.
The password + salt hash is meant to create an irreversible string, so that even the one who is responsible for securing user passwords, don't know what they are. You could take the same approach like [JWT token](
https://jwt.io/). But again, the "hacker" can only make use of the token when they have access to the server, so if they have access to the server anyway. They could just as easily proces the tokens via the exact same function as you would come up with to decode them.
Hey
@861677933810941973we understand that you'd like help with this issue—but we'd ask that you refrain from cross-posting it in other channels. It's unfortunately not possible at this time for Payload team members to address every question in our server, so we'd ask that you are patient waiting for a response from our community.
Sorry, I didn’t see your response earlier. I was away for lunch. Thanks again for your insights; they give me a clearer understanding of what I should do. You’re really a goat! 👑
Hi , Sorry about that. I will make sure to post in only one channel from now on. I sincerely hope that you will soon have the capacity to improve issue handling. Best of luck to the whole team; you’re doing a remarkable job

.
Not solved 👌
Hey I’m working on a payload OAuth implementation myself right now. Usually you save the access token either as JWT http only cookie in which case it is not accessible by JavaScript in the browser but can be send with requests, or you store it in a database and use a session to load the access token and use it whenever you make actions on the users behalf. This repo shows how both can be done
https://github.com/contentql/pin-hcmsbut I may also start a standalone plugin that creates the all the necessary fields and collections
Thank you very much, yes, a plugin would be a good idea ! 🌟
Star
Discord
online
Get dedicated engineering support directly from the Payload team.