npm.io
2.1.0 • Published 6h ago

react-linkedin-login-oauth2

Licence
MIT
Version
2.1.0
Deps
0
Vulns
0
Weekly
0
Stars
98

React Linked In Login Using OAuth 2.0

All Contributors PRs Welcome

npm package npm

Demo: https://stupefied-goldberg-b44ee5.netlify.app/

LinkedIn deprecated the legacy Sign In with LinkedIn product on August 1, 2023. Version 2 of this library is maintained for existing applications that still use the legacy r_emailaddress and r_liteprofile scopes. If you are creating a new application, use version 3 of this library with Sign In with LinkedIn using OpenID Connect.

This library completes the browser portion of LinkedIn's OAuth 2.0 authorization flow and returns an authorization code. It does not exchange that code for an access token. Your application must send the code to its backend, where the backend exchanges it with LinkedIn using the application's client secret. See Exchange the authorization code.

Table of contents

Changelog

See CHANGELOG.md

Installation

For a new application, install version 3 or above and use LinkedIn's OpenID Connect flow:

pnpm add react-linkedin-login-oauth2@^3

Only existing applications that depend on the deprecated legacy scopes should install version 2:

pnpm add react-linkedin-login-oauth2@^2

Overview

Call linkedInLogin using useLinkedIn (recommended) or the LinkedIn render-props component. A popup asks the member to authorize your application. LinkedIn then redirects the popup to your redirectUri, where LinkedInCallback sends the authorization code back to the original window. Your onSuccess callback receives that code.

The authorization code is not an access token and cannot be used directly to call LinkedIn APIs. Send it to your backend immediately and exchange it as described below.

Usage

First, we create a button and provide required props:

import { useLinkedIn } from 'react-linkedin-login-oauth2';
// You can use provided image shipped by this package or using your own
import linkedin from 'react-linkedin-login-oauth2/assets/linkedin.png';

function LinkedInPage() {
  const { linkedInLogin } = useLinkedIn({
    clientId: '86vhj2q7ukf83q',
    redirectUri: `${window.location.origin}/linkedin`, // for Next.js, you can use `${typeof window === 'object' && window.location.origin}/linkedin`
    onSuccess: (code) => {
      // Send the authorization code to your own backend.
      fetch('/api/auth/linkedin/exchange', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ code }),
      });
    },
    onError: (error) => {
      console.log(error);
    },
    popupWidth: 700,
    popupHeight: 700,
  });

  return (
    <img
      onClick={linkedInLogin}
      src={linkedin}
      alt="Sign in with Linked In"
      style={{ maxWidth: '180px', cursor: 'pointer' }}
    />
  );
}

If you do not want to use hooks, the library also provides a render-props component:

import { LinkedIn } from 'react-linkedin-login-oauth2';
// You can use provided image shipped by this package or using your own
import linkedin from 'react-linkedin-login-oauth2/assets/linkedin.png';

function LinkedInPage() {
  return (
    <LinkedIn
      clientId="86vhj2q7ukf83q"
      redirectUri={`${window.location.origin}/linkedin`}
      onSuccess={(code) => {
        console.log(code);
      }}
      onError={(error) => {
        console.log(error);
      }}
      popupWidth={700}
      popupHeight={700}
    >
      {({ linkedInLogin }) => (
        <img
          onClick={linkedInLogin}
          src={linkedin}
          alt="Sign in with Linked In"
          style={{ maxWidth: '180px', cursor: 'pointer' }}
        />
      )}
    </LinkedIn>
  );
}

Render LinkedInCallback at the path configured as your redirectUri. You can use React Router or Next.js routing.

  • React Router:
import { LinkedInCallback } from 'react-linkedin-login-oauth2';
import { BrowserRouter, Route, Routes } from 'react-router';

function Demo() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/linkedin" element={<LinkedInCallback />} />
      </Routes>
    </BrowserRouter>
  );
}
  • Next.js App Router:
// app/linkedin/page.js
'use client';

import { LinkedInCallback } from 'react-linkedin-login-oauth2';

export default function LinkedInCallbackPage() {
  return <LinkedInCallback />;
}

Exchange the authorization code

The code passed to onSuccess is short-lived. Your application should complete these steps immediately:

  1. Send the code from the browser to an endpoint on your own backend over HTTPS.
  2. From the backend, send a form-encoded POST request to https://www.linkedin.com/oauth/v2/accessToken.
  3. Include grant_type, code, client_id, client_secret, and the same redirect_uri used for authorization.
  4. Check LinkedIn's response and securely store or use the returned access token on the backend.
  5. Create your application's own login session, preferably using a secure, HTTP-only cookie.

The token exchange must run on a server. For example:

// Server-side code only. Do not include this function in a browser bundle.
async function exchangeLinkedInCode(code) {
  const body = new URLSearchParams({
    grant_type: 'authorization_code',
    code,
    client_id: process.env.LINKEDIN_CLIENT_ID,
    client_secret: process.env.LINKEDIN_CLIENT_SECRET,
    redirect_uri: process.env.LINKEDIN_REDIRECT_URI,
  });

  const response = await fetch(
    'https://www.linkedin.com/oauth/v2/accessToken',
    {
      method: 'POST',
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
      body,
    },
  );

  if (!response.ok) {
    throw new Error(`LinkedIn token exchange failed: ${response.status}`);
  }

  return response.json();
}

Your /api/auth/linkedin/exchange handler should call this function with the authorization code received from the browser. Validate the request, handle LinkedIn errors, associate the LinkedIn identity with the correct user, and avoid returning the LinkedIn access token to browser code unless your architecture specifically requires it.

See LinkedIn's official Authorization Code Flow documentation for the request fields, response format, token lifetime, and refresh behavior.

Security

Never put your LinkedIn Client Secret in frontend source code or expose it to the browser. Do not store it in VITE_*, NEXT_PUBLIC_*, or REACT_APP_* environment variables, browser storage, query strings, or the published JavaScript bundle. Anyone using the application can inspect those values.

The LinkedIn Client ID is public and may be passed to this library. The Client Secret must remain on your backend, ideally in a server-side environment variable or secret manager. Only your backend should exchange authorization codes for access tokens. Keep the returned access token secure and, where possible, use it from the backend rather than exposing it to the browser.

Support IE

  • Support for IE is dropped from version 2

Demo

Props

  • LinkedIn component:
Parameter value is required default
clientId string yes
redirectUri string yes
onSuccess function yes
onError function no
state string no randomly generated string (recommend to keep default value)
scope string no 'r_emailaddress'
See LinkedIn's OAuth permission documentation. Separate multiple scopes with a space.
popupWidth number no 600
popupHeight number no 600
closePopupMessage string no 'User closed the popup'
children function no Required when using the LinkedIn component (render props)

Reference: LinkedIn Authorization Code Flow

  • LinkedInCallback component:
    No parameters needed

Issues

Please create an issue at https://github.com/nvh95/react-linkedin-login-oauth2/issues. I will spend time to help you.

Failed to minify the code from this file: ./node_modules/react-linkedin-login-oauth2/node_modules/query-string/index.js:8

Please upgrade react-linkedin-login-oauth2 to latest version following

Follow the version-specific commands in Installation.

Known issue

Migration guide

Upgrading an existing integration from version 1? See the version 1 to version 2 migration guide.

Contributors

Thanks goes to these wonderful people (emoji key):


Hung Viet Nguyen


Nguyễn Duy Khánh


YBeck


Mehdi Raza


Phillip Denness


dsp.iam


Vitalii Bulyzhyn


Pradeep Reddy Guduru


Uric Bonatti Cardoso


faisalur-rehman


Ruslan

This project follows the all-contributors specification. Contributions of any kind welcome!

Keywords