Skip to content

Instantly share code, notes, and snippets.

@zawie
Created November 5, 2022 18:29
Show Gist options
  • Save zawie/1b47930a5505ebbd91d4b94483473de4 to your computer and use it in GitHub Desktop.
Save zawie/1b47930a5505ebbd91d4b94483473de4 to your computer and use it in GitHub Desktop.
An example of using the Google API to authenticate.
import { GoogleUserInfo } from '../model/definitions'
import HttpException from '../model/HttpException'
import { Request } from 'express';
import { getEmail } from '../accessor/database.mongo'
const fetch = require('node-fetch')
require('dotenv').config()
const { AUTH_CLIENT_ID, AUTH_CLIENT_SECRET, JWT_SECRET, AUTH_REDIRECT_URI } = process.env;
const SCOPES = ['https://www.googleapis.com/auth/userinfo.email', 'https://www.googleapis.com/auth/userinfo.profile']
const google = require('googleapis').google
const jwt = require('jsonwebtoken')
const OAuth2 = google.auth.OAuth2
const googleEndpoint = (token: string): string => `https://www.googleapis.com/oauth2/v1/userinfo?access_token=${token}`
export const getAuthClient = (): typeof OAuth2 => new OAuth2(AUTH_CLIENT_ID, AUTH_CLIENT_SECRET, AUTH_REDIRECT_URI)
export function verifyJwt(jwt_cookie: string): any {
return jwt.verify(jwt_cookie, JWT_SECRET);
}
export function generateAuthUrl(oauth2Client: typeof OAuth2 = getAuthClient()): string {
return oauth2Client.generateAuthUrl({
access_type: 'offline', // Indicates that we need to be able to access data continously without the user constantly giving us consent
scope: SCOPES // Using the access scopes from our config file
});
}
export async function getGoogleUserInfo(request: Request): Promise<GoogleUserInfo> {
// Check if their is a cookie to read.
if (!request.cookies.jwt) {
throw new HttpException(401, "No cookie found")
}
// Get creedentials from cookie.
const oauth2Client = getAuthClient()
oauth2Client.credentials = verifyJwt(request.cookies.jwt);
// Extract Google information from token.
const access_token = oauth2Client.credentials.access_token
const GoogleResponse = await fetch(googleEndpoint(access_token), { method: 'GET' })
if (!GoogleResponse) {
throw new HttpException(GoogleResponse.status, GoogleResponse.statusText)
}
return GoogleResponse.json() as Promise<GoogleUserInfo>
}
export async function isAuthorized(request: Request, aliasNeeded: string): Promise<boolean> {
try {
// Get user email and needed email.
const [{ email }, necessaryEmail] = await Promise.all([getGoogleUserInfo(request), getEmail(aliasNeeded)])
// Check if emails match.
return email === necessaryEmail
} catch {
return false
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment