UNPKG

easy-social-auth

Version:

A flexible, standalone package for social authentication using Google, Facebook & Twitter

580 lines (452 loc) 19.1 kB
# Easy Social Auth [![npm version](https://img.shields.io/npm/v/easy-social-auth)](https://www.npmjs.com/package/easy-social-auth) [![npm downloads](https://img.shields.io/npm/dm/easy-social-auth)](https://www.npmjs.com/package/easy-social-auth) [![GitHub issues](https://img.shields.io/github/issues/devjibs/easy-social-auth)](https://github.com/devjibs/easy-social-auth/issues) [![GitHub stars](https://img.shields.io/github/stars/devjibs/easy-social-auth)](https://github.com/devjibs/easy-social-auth/stargazers) ## Supported Social Authentication Providers <p align="left"> <img src="https://img.icons8.com/color/48/000000/google-logo.png" alt="Google Logo" width="40" height="40"> <img src="https://img.icons8.com/color/48/000000/facebook-new.png" alt="Facebook Logo" width="40" height="40"> <img src="https://img.icons8.com/ios-filled/50/000000/x.png" alt="X Logo" width="40" height="35"> <img src="https://img.icons8.com/fluency/48/000000/instagram-new.png" alt="Instagram Logo" width="40" height="40"> <img src="https://img.icons8.com/fluency/48/000000/tiktok.png" alt="TikTok Logo" width="40" height="40"> <img src="https://img.icons8.com/fluency/48/000000/spotify.png" alt="Spotify Logo" width="40" height="40"> <img src="https://img.icons8.com/color/48/linkedin.png" alt="LinkedIn Logo" width="40" height="40"> <img src="https://img.icons8.com/color/48/000000/reddit.png" alt="Reddit Logo" width="40" height="40"> </p> A flexible, standalone package for social authentication using Google, Facebook, Instagram, Tiktok, Spotify, LinkedIn, and Twitter(X). ## Installation ```bash npm install easy-social-auth ``` ## Usage Environment Variables ### Setup and Configuration To get started, configure your environment variables. Each platform requires specific client IDs, secrets, and endpoints. Below is a template for the .env file: ```env GOOGLE_AUTH_URL=https://google-auth-url GOOGLE_CLIENT_ID=your-google-client-id GOOGLE_CLIENT_SECRET=your-google-client-secret GOOGLE_TOKEN_ENDPOINT=https://oauth2.googleapis.com/token GOOGLE_USER_INFO_ENDPOINT=https://www.googleapis.com/oauth2/v2/userinfo FACEBOOK_AUTH_URL=facebook-auth-url FACEBOOK_APP_ID=your-facebook-app-id FACEBOOK_APP_SECRET=your-facebook-app-secret FACEBOOK_TOKEN_ENDPOINT=https://graph.facebook.com/v9.0/oauth/access_token FACEBOOK_USER_INFO_ENDPOINT=https://graph.facebook.com/me?fields=id,name,email TWITTER_AUTH_URL=twitter-auth-url TWITTER_CLIENT_ID=your-twitter-client-key TWITTER_CLIENT_SECRET=your-twitter-client-secret TWITTER_TOKEN_ENDPOINT=https://api.twitter.com/oauth2/token TWITTER_USER_INFO_ENDPOINT=https://api.x.com/2/users/me TWITTER_AUTH_URL=https://api.twitter.com/oauth2/authorize TWITTER_REVOKE_ACCESS_URL=https://api.x.com/2/oauth2/revoke OAUTH_1_0_ACCESS_TOKEN_URL=https://api.x.com/oauth/access_token OAUTH_1_0_REQUEST_TOKEN_URL=https://api.x.com/oauth/request_token TWITTER_OAUTH_1_0_URL=https://api.x.com/oauth/authorize TWITTER_CONSUMER_KEY=your-consumer-key TWITTER_CONSUMER_SECRET=your-consumer-secret INSTAGRAM_AUTH_URL=instagram-auth-url INSTAGRAM_CLIENT_ID=your-instagram-client-id INSTAGRAM_CLIENT_SECRET=your-instagram-client-secret INSTAGRAM_ACCESS_TOKEN_URL=https://api.instagram.com/oauth/access_token INSTAGRAM_LONG_LIVED_ACCESS_TOKEN_URL=https://graph.instagram.com/access_token INSTAGRAM_REFRESH_TOKEN_URL=https://graph.instagram.com/refresh_access_token INSTAGRAM_USER_INFO_ENDPOINT=https://graph.instagram.com/me?fields=id,username,account_type SPOTIFY_AUTH_URL=spotify-auth-url SPOTIFY_CLIENT_ID=your-spotify-client-id SPOTIFY_CLIENT_SECRET=your-spotify-client-secret SPOTIFY_TOKEN_ENDPOINT=https://accounts.spotify.com/api/token SPOTIFY_USER_INFO_ENDPOINT=https://api.spotify.com/v1/me TIKTOK_AUTH_URL=tiktok-auth-url TIKTOK_CLIENT_KEY=your-tiktok-client-key, TIKTOK_CLIENT_SECRET=your-tiktok-client-secret TIKTOK_TOKEN_ENDPOINT=https://open.tiktokapis.com/v2/oauth/token/ TIKTOK_USER_INFO_ENDPOINT=https://open.tiktokapis.com/v2/user/info/?fields=open_id,union_id,avatar_url,display_name LINKEDIN_AUTH_URL=https://www.linkedin.com/oauth/v2/authorization LINKEDIN_CLIENT_ID=your-linkedin-client-key LINKEDIN_CLIENT_SECRET=your-linkedin-client-secret LINKEDIN_TOKEN_ENDPOINT=https://www.linkedin.com/oauth/v2/accessToken LINKEDIN_USER_INFO_ENDPOINT=https://api.linkedin.com/v2/userinfo REDDIT_AUTH_URL=https://www.reddit.com/api/v1/authorize REDDIT_CLIENT_ID=your-reddit-client-id REDDIT_CLIENT_SECRET=your-reddit-client-secret REDDIT_TOKEN_ENDPOINT=https://www.reddit.com/api/v1/access_token REDDIT_USER_INFO_ENDPOINT=https://oauth.reddit.com/api/v1/me ``` **Note: Ensure your redirect URIs are registered in the respective developer consoles.** ## Example Usage 1. Initialize a Strategy Import and configure a strategy with the required provider credentials: ```typescript import { GoogleStrategy } from "easy-social-auth"; const googleStrategy = new GoogleStrategy({ clientId: process.env.GOOGLE_CLIENT_ID, clientSecret: process.env.GOOGLE_CLIENT_SECRET, authUrl: process.env.GOOGLE_AUTH_URL, tokenEndpoint: process.env.GOOGLE_TOKEN_ENDPOINT, userInfoEndpoint: process.env.GOOGLE_USER_INFO_ENDPOINT, }); const authUrl = googleStrategy.generateAuthUrl( "http://localhost:3000/auth/google" ); console.log("Google Auth URL:", authUrl); ``` 2. Exchange Code for Token After the user is redirected back to your app: ```typescript const tokenResponse = await googleStrategy.exchangeCodeForToken( "code", "http://localhost:3000/auth/google" ); if (tokenResponse.status) { console.log("Access Token:", tokenResponse.data); } ``` 3. Fetch User Data Retrieve user information using the access token: ```typescript const userData = await googleStrategy.getUserData(tokenResponse.data!); if (userData.status) { console.log("User Data:", userData.data); } ``` ### Examples for each strategy #### Google ```typescript import { SocialAuthService } from "easy-social-auth"; const socialAuthServiceGoogle = new SocialAuthService(); // Generate Auth URL const googleAuthUrl = socialAuthServiceGoogle.googleStrategy.generateAuthUrl( "http://localhost:3000/auth/google" ); console.log("Google Auth URL:", googleAuthUrl); // Exchange Code for Token const googleTokenResponse = await socialAuthServiceGoogle.googleStrategy.exchangeCodeForToken( "auth_code", "http://localhost:3000/auth/google" ); console.log("Google Token Response:", googleTokenResponse); // Fetch User Data if (googleTokenResponse.status) { const userData = await googleStrategy.getUserData(googleTokenResponse.data!); console.log("Google User Data:", userData); } ``` #### Facebook ```typescript import { SocialAuthService } from "easy-social-auth"; const socialAuthServiceFacebook = new SocialAuthService(); // Generate Auth URL const facebookAuthUrl = socialAuthServiceFacebook.facebookStrategy.generateAuthUrl( "http://localhost:3000/auth/facebook" ); console.log("Facebook Auth URL:", facebookAuthUrl); // Exchange Code for Token const facebookTokenResponse = await socialAuthServiceFacebook.facebookStrategy.exchangeCodeForToken( "auth_code", "http://localhost:3000/auth/facebook" ); console.log("Facebook Token Response:", facebookTokenResponse); // Fetch User Data if (facebookTokenResponse.status) { const userData = await facebookStrategy.getUserData( facebookTokenResponse.data! ); console.log("facebook User Data:", userData); } ``` #### Instagram ```typescript import { SocialAuthService } from "easy-social-auth"; const socialAuthServiceInstagram = new SocialAuthService(); // Generate Auth URL const instagramAuthUrl = socialAuthServiceInstagram.instagramStrategy.generateAuthUrl( "http://localhost:3000/auth/instagram" ); console.log("instagram Auth URL:", instagramAuthUrl); // Exchange Code for Token const instagramTokenResponse = await socialAuthServiceInstagram.instagramStrategy.exchangeCodeForToken( "auth_code", "http://localhost:3000/auth/instagram" ); console.log("Instagram Token Response:", instagramTokenResponse); // Exchange token for long lined token const instagramLongLivedTokenResponse = await socialAuthServiceInstagram.instagramStrategy.exchangeTokenforLongLivedToken( instagramTokenResponse.data ); console.log("Instagram Token Response:", instagramLongLivedTokenResponse); // Refresh Access Token const refreshedInstagramToken = await socialAuthServiceInstagram.instagramStrategy.refreshAccessToken( instagramTokenResponse.data ); console.log("Instagram Refresh Token Response:", instagramRefreshedToken); // Fetch User Data if (instagramTokenResponse.status) { const userData = await instagramStrategy.getUserData( instagramTokenResponse.data! ); console.log("Instagram User Data:", userData); } ``` #### LinkedIn ```typescript import { SocialAuthService } from "easy-social-auth"; const socialAuthServiceLinkedIn = new SocialAuthService(); // Generate Auth URL const linkedinAuthUrl = socialAuthServiceLinkedin.linkedinStrategy.generateAuthUrl( "http://localhost:3000/auth/linkedin" ); console.log("Linkedin Auth URL:", linkedinAuthUrl); // Exchange Code for Token const linkedinTokenResponse = await socialAuthServiceLinkedin.linkedinStrategy.exchangeCodeForToken( "auth_code", "http://localhost:3000/auth/linkedin" ); console.log("Linkedin Token Response:", linkedinTokenResponse); // Request App Token const linkedinAppToken = await socialAuthServiceLinkedin.linkedinStrategy.requestAppToken(); console.log("Linkedin App Token Response:", linkedinAppToken); // Fetch User Data if (linkedinTokenResponse.status) { const userData = await linkedinStrategy.getUserData( linkedinTokenResponse.data! ); console.log("Linkedin User Data:", userData); } ``` #### Spotify ```typescript import { SocialAuthService } from "easy-social-auth"; const socialAuthServiceSpotify = new SocialAuthService(); // Generate Auth URL const spotifyAuthUrl = socialAuthServiceSpotify.spotifyStrategy.generateAuthUrl( "http://localhost:3000/auth/spotify" ); console.log("Spotify Auth URL:", spotifyAuthUrl); // Exchange Code for Token const spotifyTokenResponse = await socialAuthServiceSpotify.spotifyStrategy.exchangeCodeForToken( "auth_code", "http://localhost:3000/auth/spotify" ); console.log("Spotify Token Response:", spotifyTokenResponse); // Refresh Access Token const refreshedSpotifyToken = await socialAuthServiceSpotify.spotifyStrategy.refreshAccessToken( spotifyTokenResponse.data.refreshToken ); console.log("Spotify Refresh Token Response:", spotifyRefreshedToken); // Fetch User Data if (spotifyTokenResponse.status) { const userData = await spotifyStrategy.getUserData( spotifyTokenResponse.data! ); console.log("Spotify User Data:", userData); } ``` #### Tiktok ```typescript import { SocialAuthService } from "easy-social-auth"; const socialAuthServiceTiktok = new SocialAuthService(); // Generate Auth URL const tiktokAuthUrl = socialAuthServiceTiktok.tiktokStrategy.generateAuthUrl( "http://localhost:3000/auth/tiktok" ); console.log("Tiktok Auth URL:", tiktokAuthUrl); // Exchange Code for Token const tiktokTokenResponse = await socialAuthServiceTiktok.tiktokStrategy.exchangeCodeForToken( "auth_code", "http://localhost:3000/auth/tiktok" ); console.log("Tiktok Token Response:", tiktokTokenResponse); // Refresh Access Token const refreshedTiktokToken = await socialAuthServiceTiktok.tiktokStrategy.refreshAccessToken( tiktokTokenResponse.data.refreshToken ); console.log("Tiktok Refresh Token Response:", tiktokRefreshedToken); // Fetch User Data if (tiktokTokenResponse.status) { const userData = await tiktokStrategy.getUserData(tiktokTokenResponse.data!); console.log("Tiktok User Data:", userData); } ``` #### Twitter ```typescript import { SocialAuthService } from "easy-social-auth"; const socialAuthServiceTwitter = new SocialAuthService(); // Generate Auth URL const twitterAuthUrl = socialAuthServiceTwitter.twitterStrategy.generateAuthUrl( "http://localhost:3000/auth/twitter" ); console.log("Twitter Auth URL:", twitterAuthUrl); // Exchange Code for Token const twitterTokenResponse = await socialAuthServiceTwitter.twitterStrategy.exchangeCodeForToken( "auth_code", "http://localhost:3000/auth/twitter" ); console.log("Twitter Token Response:", twitterTokenResponse); // Refresh Access Token const refreshedTwitterToken = await socialAuthServiceTwitter.twitterStrategy.refreshAccessToken( twitterTokenResponse.data.refreshToken ); console.log("Twitter Refresh Token Response:", twitterRefreshedToken); // Request App Token const twitterAppToken = await socialAuthServiceTwitter.twitterStrategy.requestAppToken( "scope", "client_type (optional)" ); console.log("Twitter App Token Response:", twitterAppToken); // Revoke Access Token const revokeTwitterTokenResponse = await socialAuthServiceTwitter.twitterStrategy.revokeToken( "token", "token_type_hint (optional (refresh_token || access_token))" ); console.log("Twitter Revoke Token Response:", revokeTwitterTokenResponse); // Fetch User Data if (twitterTokenResponse.status) { const userData = await twitterStrategy.getUserData( twitterTokenResponse.data! ); console.log("Twitter User Data:", userData); } ``` #### Reddit ```typescript import { SocialAuthService } from 'easy-social-auth'; const socialAuthServiceReddit = new SocialAuthService(); // Generate Auth URL const redditAuthUrl = socialAuthServiceReddit.redditStrategy.generateAuthUrl("http://localhost:3000/auth/reddit"); console.log("Reddit Auth URL:", redditAuthUrl); // Exchange Code for Token const redditTokenResponse = await socialAuthServicereddit.redditStrategy.exchangeCodeForToken("auth_code", "http://localhost:3000/auth/reddit"); console.log("reddit Token Response:", redditTokenResponse); // Refresh Access Token const refreshedRedditToken = await socialAuthServiceReddit.redditStrategy.refreshAccessToken(redditTokenResponse.data.refreshToken); console.log("Reddit Refresh Token Response:", redditRefreshedToken); // Request App Token const redditAppToken = await socialAuthServiceReddit.redditStrategy.requestAppToken( "scope", "client_type (optional)", ); console.log("Reddit App Token Response:", redditAppToken); // Revoke Access Token const revokeRedditTokenResponse = await socialAuthServiceReddit.redditStrategy.revokeToken( "token", "token_type_hint (optional (refresh_token || access_token))", ); console.log("Reddit Revoke Token Response:", revokeRedditTokenResponse); // Fetch User Data if (redditTokenResponse.status) { const userData = await redditStrategy.getUserData(redditTokenResponse.data!); console.log("Reddit User Data:", userData); } ``` ### Example with Multiple Strategies ```typescript import { GoogleStrategy, FacebookStrategy } from "easy-social-auth"; const googleStrategy = new GoogleStrategy({...}); const facebookStrategy = new FacebookStrategy({...}); // Authenticate with Google const googleAuthUrl = googleStrategy.generateAuthUrl("http://localhost:3000/auth/google"); console.log("Google Auth URL:", googleAuthUrl); // Authenticate with Facebook const fbAuthUrl = facebookStrategy.generateAuthUrl("http://localhost:3000/auth/facebook"); console.log("Facebook Auth URL:", fbAuthUrl); ``` ### Example with Custom Config ```typescript import { LinkedinStrategy, ILinkedinConfig } from "easy-social-auth"; const customConfig: ILinkedinConfig = { clientId: YOUR_LINKEDIN_CLIENT_ID, clientSecret: YOUR_LINKEDIN_CLIENT_SECRET, tokenEndpoint: "https://www.linkedin.com/oauth/v2/accessToken", userInfoEndpoint: "https://api.linkedin.com/v2/userinfo", authUrl: "https://www.linkedin.com/oauth/v2/authorization", }; linkedinStrategy = new LinkedinStrategy(customConfig); // Generate Auth URL const linkedinAuthUrl = linkedinStrategy.generateAuthUrl( "http://localhost:3000/auth/linkedin" ); console.log("Linkedin Auth URL:", linkedinAuthUrl); // Exchange Code for Token const linkedinTokenResponse = await linkedinStrategy.exchangeCodeForToken( "auth_code", "http://localhost:3000/auth/linkedin" ); console.log("Linkedin Token Response:", linkedinTokenResponse); // Request App Token const linkedinAppToken = await linkedinStrategy.requestAppToken(); console.log("Linkedin App Token Response:", linkedinAppToken); // Fetch User Data if (linkedinTokenResponse.status) { const userData = await linkedinStrategy.getUserData( linkedinTokenResponse.data! ); console.log("Linkedin User Data:", userData); } ``` ## API ### Generate Auth Url `generateAuthUrl(redirectUri: string, scope?: string): string` Generates the authorization URL for the specified authentication type. Parameters: `redirectUri` (`string`): The redirect URI for the authentication. `scope` (`string`, optional): An optional scope parameter to include in the URL. Returns: `string`: The generated authorization URL. ### Exchange Code for Token `exchangeCodeForToken(code: string, redirectUri: string, additionalParams?: Record<string, string>): Promise<SocialAuthResponse<string>>` Exchanges an authorization code for an access token. Parameters: `code` (`string`): The authorization code received from the authentication provider. `redirectUri` (`string`): The redirect URI used in the authentication request. `additionalParams` (`Record<string, string>`, optional): Additional parameters for the token exchange request. Returns: `Promise<SocialAuthResponse<string>>`: A promise that resolves to the `SocialAuthResponse` containing the access token. ### Refresh Access Token `refreshAccessToken(refreshToken: string): Promise<SocialAuthResponse<string>>` Refreshes an access token using a refresh token. Parameters: `refreshToken` (`string`): The refresh token received from the authentication provider. Returns: `Promise<SocialAuthResponse<string>>`: A promise that resolves to the `SocialAuthResponse` containing the new access token. ### Exchange Password for Token `exchangePasswordForToken(username: string, password: string): Promise<SocialAuthResponse<string>>` Exchanges a username and password for an access token. Parameters: `username` (`string`): The username. `password` (`string`): The password. Returns: `Promise<SocialAuthResponse<string>>`: A promise that resolves to the `SocialAuthResponse` containing the access token. ### Get User Data `getUserData(accessToken: string): Promise<SocialAuthResponse<ISocialUser>>` Retrieves user data for the specified authentication type using the access token. Parameters: `accessToken` (`string`): The access token received from the authentication provider. Returns: `Promise<SocialAuthResponse<ISocialUser>>`: A promise that resolves to the `SocialAuthResponse` containing the user data. ### Troubleshooting Invalid Redirect URI: Ensure the redirect URI matches the one configured in the provider console. Token Errors: Verify the client ID, secret, and token endpoint. ### Contributing Feel free to open issues or contribute improvements via pull requests on GitHub. ### End