This repository is all in one, includes multiple platform for social login, is written by TypeScript and React Hooks, tree-shakeable, zero dependencies, extremely lightweight.
You can customize any style UI as you like.
Reactjs Social Login is an HOC which provides social login through multiple providers.
Currently supports Amazon, Facebook, GitHub, Google, Instagram, Linkedin, Pinterest, Twitter, Microsoft, Apple, Tiktok as providers (more to come!)
importReact,{useCallback,useState}from'react'import'./app.css'import{User}from'./User'// component display user (see detail on /example directory)import{LoginSocialGoogle,LoginSocialAmazon,LoginSocialFacebook,LoginSocialGithub,LoginSocialInstagram,LoginSocialLinkedin,LoginSocialMicrosoft,LoginSocialPinterest,LoginSocialTwitter,LoginSocialApple,LoginSocialTiktok,IResolveParams,}from'reactjs-social-login'// CUSTOMIZE ANY UI BUTTONimport{FacebookLoginButton,GoogleLoginButton,GithubLoginButton,AmazonLoginButton,InstagramLoginButton,LinkedInLoginButton,MicrosoftLoginButton,TwitterLoginButton,AppleLoginButton,}from'react-social-login-buttons'import{ReactComponentasPinterestLogo}from'./assets/pinterest.svg'import{ReactComponentasTiktokLogo}from'./assets/tiktok.svg'// REDIRECT URL must be same with URL where the (reactjs-social-login) components is locate// MAKE SURE the (reactjs-social-login) components aren't unmounted or destroyed before the ask permission dialog closesconstREDIRECT_URI=window.location.href;constApp=()=>{const[provider,setProvider]=useState('')const[profile,setProfile]=useState<any>()constonLoginStart=useCallback(()=>{alert('login start')},[])constonLogoutSuccess=useCallback(()=>{setProfile(null)setProvider('')alert('logout success')},[])return(<>{provider&&profile ? (<Userprovider={provider}profile={profile}onLogout={onLogoutSuccess}/>) : (<divclassName={`App ${provider&&profile ? 'hide' : ''}`}><h1className='title'>ReactJS Social Login</h1><LoginSocialFacebookisOnlyGetTokenappId={process.env.REACT_APP_FB_APP_ID||''}onLoginStart={onLoginStart}onResolve={({ provider, data }: IResolveParams)=>{setProvider(provider)setProfile(data)}}onReject={(err)=>{console.log(err)}}><FacebookLoginButton/></LoginSocialFacebook><LoginSocialGoogleisOnlyGetTokenclient_id={process.env.REACT_APP_GG_APP_ID||''}onLoginStart={onLoginStart}onResolve={({ provider, data }: IResolveParams)=>{setProvider(provider)setProfile(data)}}onReject={(err)=>{console.log(err)}}><GoogleLoginButton/></LoginSocialGoogle><LoginSocialAppleclient_id={process.env.REACT_APP_APPLE_ID||''}scope={'name email'}redirect_uri={REDIRECT_URI}onLoginStart={onLoginStart}onResolve={({ provider, data }: IResolveParams)=>{setProvider(provider);setProfile(data);}}onReject={err=>{console.log(err);}}><AppleLoginButton/></LoginSocialApple><LoginSocialAmazonisOnlyGetTokenclient_id={process.env.REACT_APP_AMAZON_APP_ID||''}redirect_uri={REDIRECT_URI}onResolve={({ provider, data }: IResolveParams)=>{setProvider(provider)setProfile(data)}}onReject={(err: any)=>{console.log(err)}}onLoginStart={onLoginStart}><AmazonLoginButton/></LoginSocialAmazon><LoginSocialInstagramisOnlyGetTokenclient_id={process.env.REACT_APP_INSTAGRAM_APP_ID||''}client_secret={process.env.REACT_APP_INSTAGRAM_APP_SECRET||''}redirect_uri={REDIRECT_URI}onLoginStart={onLoginStart}onResolve={({ provider, data }: IResolveParams)=>{setProvider(provider)setProfile(data)}}onReject={(err: any)=>{console.log(err)}}><InstagramLoginButton/></LoginSocialInstagram><LoginSocialMicrosoftisOnlyGetTokenclient_id={process.env.REACT_APP_MICROSOFT_APP_ID||''}redirect_uri={REDIRECT_URI}onLoginStart={onLoginStart}onResolve={({ provider, data }: IResolveParams)=>{setProvider(provider)setProfile(data)}}onReject={(err: any)=>{console.log(err)}}><MicrosoftLoginButton/></LoginSocialMicrosoft><LoginSocialLinkedinisOnlyGetTokenclient_id={process.env.REACT_APP_LINKEDIN_APP_ID||''}client_secret={process.env.REACT_APP_LINKEDIN_APP_SECRET||''}redirect_uri={REDIRECT_URI}onLoginStart={onLoginStart}onResolve={({ provider, data }: IResolveParams)=>{setProvider(provider)setProfile(data)}}onReject={(err: any)=>{console.log(err)}}><LinkedInLoginButton/></LoginSocialLinkedin><LoginSocialGithubisOnlyGetTokenclient_id={process.env.REACT_APP_GITHUB_APP_ID||''}client_secret={process.env.REACT_APP_GITHUB_APP_SECRET||''}redirect_uri={REDIRECT_URI}onLoginStart={onLoginStart}onResolve={({ provider, data }: IResolveParams)=>{setProvider(provider)setProfile(data)}}onReject={(err: any)=>{console.log(err)}}><GithubLoginButton/></LoginSocialGithub><LoginSocialPinterestisOnlyGetTokenclient_id={process.env.REACT_APP_PINTEREST_APP_ID||''}client_secret={process.env.REACT_APP_PINTEREST_APP_SECRET||''}redirect_uri={REDIRECT_URI}onLoginStart={onLoginStart}onResolve={({ provider, data }: IResolveParams)=>{setProvider(provider)setProfile(data)}}onReject={(err: any)=>{console.log(err)}}className='pinterest-btn'><divclassName='content'><divclassName='icon'><PinterestLogo/></div><spanclassName='txt'>Login With Pinterest</span></div></LoginSocialPinterest><LoginSocialTwitterisOnlyGetTokenclient_id={process.env.REACT_APP_TWITTER_V2_APP_KEY||''}redirect_uri={REDIRECT_URI}onLoginStart={onLoginStart}onResolve={({ provider, data }: IResolveParams)=>{setProvider(provider)setProfile(data)}}onReject={(err: any)=>{console.log(err)}}><TwitterLoginButton/></LoginSocialTwitter><LoginSocialTiktokclient_key={process.env.REACT_APP_TIKTOK_CLIENT_KEY}redirect_uri={REDIRECT_URI}onLoginStart={onLoginStart}onResolve={({ provider, data })=>{setProvider(provider);setProfile(data);}}onReject={(err)=>{console.log(err);}}className="pinterest-btn"><divclassName="content"><divclassName="icon"><TiktokLogo/></div><spanclassName="txt">Login With Tiktok</span></div></LoginSocialTiktok></div>)}</>)}exportdefaultApp
JavaScript Version
importReact,{useCallback,useState}from'react'import'./app.css'import{User}from'./User'// component display user (see detail on /example directory)import{LoginSocialGoogle,LoginSocialAmazon,LoginSocialFacebook,LoginSocialGithub,LoginSocialInstagram,LoginSocialLinkedin,LoginSocialMicrosoft,LoginSocialPinterest,LoginSocialTwitter,LoginSocialApple,LoginSocialTiktok,}from'reactjs-social-login'// CUSTOMIZE ANY UI BUTTONimport{FacebookLoginButton,GoogleLoginButton,GithubLoginButton,AmazonLoginButton,InstagramLoginButton,LinkedInLoginButton,MicrosoftLoginButton,TwitterLoginButton,AppleLoginButton,}from'react-social-login-buttons'import{ReactComponentasPinterestLogo}from'./assets/pinterest.svg'import{ReactComponentasTiktokLogo}from'./assets/tiktok.svg'// REDIRECT URL must be same with URL where the (reactjs-social-login) components is locate// MAKE SURE the (reactjs-social-login) components aren't unmounted or destroyed before the ask permission dialog closesconstREDIRECT_URI=window.location.href;constApp=()=>{const[provider,setProvider]=useState('')const[profile,setProfile]=useState(null)constonLoginStart=useCallback(()=>{alert('login start')},[])constonLogoutSuccess=useCallback(()=>{setProfile(null)setProvider('')alert('logout success')},[])return(<>{provider&&profile ? (<Userprovider={provider}profile={profile}onLogout={onLogoutSuccess}/>) : (<divclassName={`App ${provider&&profile ? 'hide' : ''}`}><h1className='title'>ReactJS Social Login</h1><LoginSocialFacebookisOnlyGetTokenappId={process.env.REACT_APP_FB_APP_ID||''}onLoginStart={onLoginStart}onResolve={({ provider, data })=>{setProvider(provider)setProfile(data)}}onReject={(err)=>{console.log(err)}}><FacebookLoginButton/></LoginSocialFacebook><LoginSocialGoogleisOnlyGetTokenclient_id={process.env.REACT_APP_GG_APP_ID||''}onLoginStart={onLoginStart}onResolve={({ provider, data })=>{setProvider(provider)setProfile(data)}}onReject={(err)=>{console.log(err)}}><GoogleLoginButton/></LoginSocialGoogle><LoginSocialAppleclient_id={process.env.REACT_APP_APPLE_ID||''}scope={'name email'}redirect_uri={REDIRECT_URI}onLoginStart={onLoginStart}onResolve={({ provider, data })=>{setProvider(provider);setProfile(data);}}onReject={err=>{console.log(err);}}><AppleLoginButton/></LoginSocialApple><LoginSocialAmazonisOnlyGetTokenclient_id={process.env.REACT_APP_AMAZON_APP_ID||''}redirect_uri={REDIRECT_URI}onResolve={({ provider, data })=>{setProvider(provider)setProfile(data)}}onReject={(err)=>{console.log(err)}}onLoginStart={onLoginStart}><AmazonLoginButton/></LoginSocialAmazon><LoginSocialInstagramisOnlyGetTokenclient_id={process.env.REACT_APP_INSTAGRAM_APP_ID||''}client_secret={process.env.REACT_APP_INSTAGRAM_APP_SECRET||''}redirect_uri={REDIRECT_URI}onLoginStart={onLoginStart}onResolve={({ provider, data })=>{setProvider(provider)setProfile(data)}}onReject={(err)=>{console.log(err)}}><InstagramLoginButton/></LoginSocialInstagram><LoginSocialMicrosoftisOnlyGetTokenclient_id={process.env.REACT_APP_MICROSOFT_APP_ID||''}redirect_uri={REDIRECT_URI}onLoginStart={onLoginStart}onResolve={({ provider, data })=>{setProvider(provider)setProfile(data)}}onReject={(err)=>{console.log(err)}}><MicrosoftLoginButton/></LoginSocialMicrosoft><LoginSocialLinkedinisOnlyGetTokenclient_id={process.env.REACT_APP_LINKEDIN_APP_ID||''}client_secret={process.env.REACT_APP_LINKEDIN_APP_SECRET||''}redirect_uri={REDIRECT_URI}onLoginStart={onLoginStart}onResolve={({ provider, data })=>{setProvider(provider)setProfile(data)}}onReject={(err)=>{console.log(err)}}><LinkedInLoginButton/></LoginSocialLinkedin><LoginSocialGithubisOnlyGetTokenclient_id={process.env.REACT_APP_GITHUB_APP_ID||''}client_secret={process.env.REACT_APP_GITHUB_APP_SECRET||''}redirect_uri={REDIRECT_URI}onLoginStart={onLoginStart}onResolve={({ provider, data })=>{setProvider(provider)setProfile(data)}}onReject={(err)=>{console.log(err)}}><GithubLoginButton/></LoginSocialGithub><LoginSocialPinterestisOnlyGetTokenclient_id={process.env.REACT_APP_PINTEREST_APP_ID||''}client_secret={process.env.REACT_APP_PINTEREST_APP_SECRET||''}redirect_uri={REDIRECT_URI}onLoginStart={onLoginStart}onResolve={({ provider, data })=>{setProvider(provider)setProfile(data)}}onReject={(err)=>{console.log(err)}}className='pinterest-btn'><divclassName='content'><divclassName='icon'><PinterestLogo/></div><spanclassName='txt'>Login With Pinterest</span></div></LoginSocialPinterest><LoginSocialTwitterisOnlyGetTokenclient_id={process.env.REACT_APP_TWITTER_V2_APP_KEY||''}redirect_uri={REDIRECT_URI}onLoginStart={onLoginStart}onResolve={({ provider, data })=>{setProvider(provider)setProfile(data)}}onReject={(err)=>{console.log(err)}}><TwitterLoginButton/></LoginSocialTwitter><LoginSocialTiktokclient_key={process.env.REACT_APP_TIKTOK_CLIENT_KEY}redirect_uri={REDIRECT_URI}onLoginStart={onLoginStart}onResolve={({ provider, data })=>{setProvider(provider);setProfile(data);}}onReject={(err)=>{console.log(err);}}className="pinterest-btn"><divclassName="content"><divclassName="icon"><TiktokLogo/></div><spanclassName="txt">Login With Tiktok</span></div></LoginSocialTiktok></div>)}</>)}exportdefaultApp
Loading more information like: user info, access_token on client side is discouraged and causes slow response, this should be done on server side, you can pass suggestion isOnlyGetCode={true} if you just want the code and don't need the access_token or isOnlyGetToken={true} if you just want the access_token and don't need the user's profile
1. Google Props
Prop
Type
Default
Description
onResolve
function({provider, data}) { // } (required)
-
Return provider and data (include user's info & access_token,...)
onReject
function(err) { // } (required)
-
Return error
onLoginStart
function() { // } (optional)
-
Called when click login
client_id
string (required)
-
ID application
typeResponse
accessToken / idToken (optional)
accessToken
whether get idToken or accessToken
auto_select
boolean (optional)
false
if an ID token is automatically returned without any user interaction when there's only one Google session that has approved your app before
scope
string (optional)
https://www.googleapis.com/auth/userinfo.profile
Scope application
className
string (optional)
-
Class container
isOnlyGetToken
boolean (optional)
false
Only get access_token without get user's info (server-side)
After clicking the authorize app button in the popup for twitter login I see that a network request is made and I receive this error. It seems like the request to https://cors.bridged.cc is expecting some authorization header which isn't present. I dug through your code and noticed that there is some key that you are passing "PASS_CORS_KEY" but this key is not present in the package (obviously). Could you tell me how to get this key and allow us to pass our own version into LoginSocialTwitter?
Describe the problem:
I am migrating to google identity services to implement Google One Tap SignIn in my react project with typeResponse="idToken"
One tap prompt is well displayed when user has account logged to chrome. But when user in guest mode, I am expecting to see the Warm welcome page which allows user to sigh up to the account if they wish.
What I noticed is that on firefox I can see the popin which allows to login/register with google.
Is your feature request related to a problem? Please describe.
I need to prevent user to click LoginSocialLinkedin button before some kind of Agreement checkbox.
So I try to use disabled=true attribute to make LoginSocialLinkedin disabled.
But I got this error : Property 'disabled' does not exist on type 'IntrinsicAttributes & Props'
I also try put AppButton within LoginSocialLinkedin and make AppButton disabled. The button show disabled, but it can still click and show linkedin login.
Describe the solution you'd like
LoginSocial plugin should support disabled attribute similar to other control like AppButton.
I only see the access_token in the response. I have tried different options but still can't get id_token (JWT). Is it possible to get it from the client directly without a server?
In my setup, I have reactjs application on the front end side and nestjs on the back end.
Because of API, I would like to use an authorization code to get the user information on the back end side, but currently as far as I've tested for facebook and google the code is automatically used by the onGetMe function to get the user information.
How can I prevent this function from being called and get the authorization code on the onResolve function to be able to send it to my API?
Describe the bug
When I double click the social buttons it does 2 requests, the SDK popup reopens and onResolve is called twice etc.
I've tried setting isDisabled to true on the first click but that didn't help.
I believe there was logic to prevent this before, but it was removed here to fix another issue? f8eee2d
It would be great if some logic could be added again so the buttons can only be clicked again after the previous click was resolved/rejected (without recreating the previous issue where the button couldn't be reclicked if the login was cancelled by the user).
To Reproduce
It can be reproduced with the example demo if you remove the alert in onLoginStart and then click for example the Facebook button multiple times
Hey I'm using this library with nextjs and have this configuration for twitter the dialogue for Login shows and when I authorize APP it sends an API request to https://cors.bridged.cc/https://api.twitter.com/2/oauth2/token
this API fails with 401. Any idea what I'm doing wrong or is it something from the library?
>npm i reactjs-social-login
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: [email protected]
npm ERR! Found: [email protected]
npm ERR! node_modules/react
npm ERR! react@"^18.0.0" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^17.0.1" from [email protected]
npm ERR! node_modules/reactjs-social-login
npm ERR! reactjs-social-login@"*" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR!
npm ERR! See ...\AppData\Local\npm-cache\eresolve-report.txt for a full report.
npm ERR! A complete log of this run can be found in:
npm ERR! ...\Local\npm-cache\_logs\2022-04-19T07_01_58_670Z-debug-0.log
Describe the bug
After I close the popup window from Facebook/Google/Amazon to cancel, reclicking the button doesn't work untill I refresh the page. I don't have this issue with the other buttons from Instagram etc.
When displaying a Google login button with React devtools, the following is sent to the browser's console:
Your client application uses libraries for user authentication or authorization that will soon be deprecated. See the Migration Guide for more information.
Also, listed in one of the benefits of the Google Identity Services is "the option to add user sign-in to your site's static content using just HTML". It would be great to implement that as well since I find the Google button takes a second or two longer to load than the Facebook one.
ReferenceError: require is not defined in ES module scope, you can use import instead
This file is being treated as an ES module because it has a '.js' file extension and 'app/node_modules/reactjs-social-login/package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.
Describe the bug
If I click the close icon in Google modal and I want to login again, the modal does not open without clearing the Browser memory. These periods are also included in the google document. But at least the google button should have the information that I was signed in before and it should open when I click it. For example, you can take a look at Twitter.
Describe the bug*
After clicking the log in with Google button, an intermediate object is logged onto the console.
The object contains the client Id and I don't think that's safe. I don't know if it happens because it takes too long to even load in the first place or if it's for some other reason.
To Reproduce
Steps to reproduce the behavior:
Click on 'Log In with google' button
Open the console
Data is logged in line 1 of reactjs-social-login.modern.js
Expected behavior
No logging of sensitive information
Desktop (please complete the following information):
It would be great if it was possible to pass down a param to only execute onLogin without calling getAccessToken and getProfile.
Essentially all that we need is the auth code that is coming back from the original authorization window, then we handle the rest server side, so no need to exchange the code and grab profile data. Will be great if you can make an option for that!
I see some of the social media platforms need to use the client secret that visible for end users in the example. I think it doesn't make sense to use the client secret this way and I consider that as a security vulnerability. So, does that matter if we use the client secret this way?
<LoginSocialInstagramisOnlyGetTokenclient_id={"1024858944679033"}client_secret="ac6793cb58a36f1a18d99b629f1408a6"redirect_uri={REDIRECT_URI}onLoginStart={onLoginStart}onResolve={({ provider, data })=>{setProvider(provider);setProfile(data);}}onReject={(err)=>{console.log(err);}}><InstagramLoginButton/></LoginSocialInstagram>
Describe the bug
In my app after I login with LoginSocialGoogle I go to a different page without the LoginSocialGoogle component. Then when I logout and go back to login again the button doesn't work.
Looking at your source code I found that the reason is because after the LoginSocialGoogle dismounts and then mounts again, the SDK script is still in the DOM so if (checkIsExistsSDKScript()) is true and isSdkLoaded is set to true, but instance is still null because it got reset when the component dismounted, so then this check if (instance) instance.requestAccessToken() won't succeed.
I made a workaround to fix the issue in my app by removing the SDK script when the component dismounts in a useEffect cleanup function. That way when the component mounts again checkIsExistsSDKScript() will return false and the script and instance are set again.
But maybe you could add a fix in your library instead?
To Reproduce
In your demo the issue doesn't happen because when you login the LoginSocialGoogle component doesn't actually dismount, it is only hidden with <div className={`App ${provider && profile ? 'hide' : ''}`}>. So to reproduce the issue you should render LoginSocialGoogle conditionally so it dismounts after logging in`
After making that change
Login with the Google button
Logout
Click the Google button again
Expected behavior
After dismounting and remounting the LoginSocialGoogle component and clicking the Google login button a 2nd time requestAccessToken should be called again as before
Hi ,
I encountered a problem when adding the package to my project. I use react 17.0.2 with typescript and when adding the button for the connection with Facebook, the project stops working when calling the connection page with the following message:
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
You might have more than one copy of React in the same app
See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem
Good Morning,
Regarding Linked In
I am trying to get access tokens by using auth code. but I am not able to retrieve the access token it is giving below error.
Curl To Get Access Token:
curl --location -g --request POST 'https://www.linkedin.com/oauth/v2/accessToken?client_id={{CLIENT_ID}}&grant_type=authorization_code&client_secret={{CLIENT_SECRET}}&redirect_uri=http://localhost:8000/app/&code={{AUTH_CODE}}'
--header 'Content-Type: application/x-www-form-urlencoded'
--header 'Cookie: bcookie="v=2&3f8f0496-266a-4b58-8e31-de7bcb0b4335"; lang=v=2&lang=en-us; lidc="b=OB15:s=O:r=O:a=O:p=O:g=3349:u=15:x=1:i=1645891377:t=1645977777:v=2:sig=AQHemytg36vYW-bZISZrBOR9NZ5RcnfK"; bscookie="v=1&20220225065334e2c41646-ffef-4358-8108-4102f1456b06AQECWF_H_IfxpOayfaZt98rtaFFxMJDe"; bcookie="v=2&3f8f0496-266a-4b58-8e31-de7bcb0b4335"; lang=v=2&lang=en-us; lidc="b=OB15:s=O:r=O:a=O:p=O:g=3349:u=15:x=1:i=1645891377:t=1645977777:v=2:sig=AQHemytg36vYW-bZISZrBOR9NZ5RcnfK"; bscookie="v=1&20220225065334e2c41646-ffef-4358-8108-4102f1456b06AQECWF_H_IfxpOayfaZt98rtaFFxMJDe"'
The error I am Getting:
{
"error": "invalid_request",
"error_description": "Unable to retrieve access token: appid/redirect uri/code verifier does not match authorization code. Or authorization code expired. Or external member binding exists"
}
While login with Instagram it's only giving tokes as a response. It's not giving any profile-related info including user id.
is there any method to get the user info?
Describe the bug
I want to get the user code from my reactjs application. I will then pass the code to my server-side to get the auth-token along with refresh token. UUnfortunately, I am getting profile info and access token only. I could not get the code.
To Reproduce
Steps to reproduce the behavior:
<LoginSocialGoogle
isOnlyGetCode={true}
client_id={socialAuthProps.google.key}
onLoginStart={onLoginStart}
onResolve={({ provider, data }) => {
setProvider(provider)
setProfile(data)
}}
onReject={(err) => {
console.log(err)
}}
>
<GoogleLoginButton />
</LoginSocialGoogle>```
**Expected behavior**
code in the response
**Desktop (please complete the following information):**
- OS: Macintosh
- Browser Chrome
- Version 106
When the LinkedIn popup opens up and the user logs in successfully, the redirect URL opens up in the same popup. How to force it to return back to the parent window?
When clicking on the google component it does not open the popup to enter the credentials. From what I can see, the problem is that it cannot find the google SDK. It also does not work in the Demo link of the library: https://react-social-login.netlify.app/