Gathering detailed insights and metrics for react-oauth2-code-pkce
Gathering detailed insights and metrics for react-oauth2-code-pkce
Gathering detailed insights and metrics for react-oauth2-code-pkce
Gathering detailed insights and metrics for react-oauth2-code-pkce
pkce-challenge
Generate or verify a Proof Key for Code Exchange (PKCE) challenge pair
angular-auth-oidc-client
Angular Lib for OpenID Connect & OAuth2
@badgateway/oauth2-client
OAuth2 client for browsers and Node.js. Tiny footprint, PKCE support
angular-oauth2-oidc
Support for OAuth 2 and OpenId Connect (OIDC) in Angular. Already prepared for the upcoming OAuth 2.1.
Provider agnostic OAuth2 Authorization Code flow with PKCE for React
npm install react-oauth2-code-pkce
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
126 Stars
195 Commits
52 Forks
6 Watching
2 Branches
16 Contributors
Updated on 24 Nov 2024
Minified
Minified + Gzipped
TypeScript (87.18%)
JavaScript (12%)
HTML (0.82%)
Cumulative downloads
Total Downloads
Last day
4.2%
1,452
Compared to previous day
Last week
5.5%
6,895
Compared to previous week
Last month
13.9%
26,892
Compared to previous month
Last year
72.6%
235,337
Compared to previous year
1
2
React package for OAuth2 Authorization Code flow with PKCE
Adhering to the RFCs recommendations, cryptographically sound, and with zero dependencies!
Short version;
The modern and secure way to do authentication for mobile and web applications!
Long version;
https://www.rfc-editor.org/rfc/rfc6749.html
https://datatracker.ietf.org/doc/html/rfc7636
https://oauth.net/2/pkce/
1import { AuthContext, AuthProvider, TAuthConfig, TRefreshTokenExpiredEvent } from "react-oauth2-code-pkce" 2 3const authConfig: TAuthConfig = { 4 clientId: 'myClientID', 5 authorizationEndpoint: 'https://myAuthProvider.com/auth', 6 tokenEndpoint: 'https://myAuthProvider.com/token', 7 redirectUri: 'http://localhost:3000/', 8 scope: 'someScope openid', 9 onRefreshTokenExpire: (event: TRefreshTokenExpiredEvent) => event.logIn(undefined, undefined, "popup"), 10} 11 12const UserInfo = (): JSX.Element => { 13 const {token, tokenData} = useContext<IAuthContext>(AuthContext) 14 15 return <> 16 <h4>Access Token</h4> 17 <pre>{token}</pre> 18 <h4>User Information from JWT</h4> 19 <pre>{JSON.stringify(tokenData, null, 2)}</pre> 20 </> 21} 22 23ReactDOM.render(<AuthProvider authConfig={authConfig}> 24 <UserInfo/> 25 </AuthProvider> 26 , document.getElementById('root'), 27)
For more advanced examples, see ./examples/
.
The package is available on npmjs.com here; https://www.npmjs.com/package/react-oauth2-code-pkce
1npm install react-oauth2-code-pkce
The object that's returned by useContext(AuthContext)
provides these values;
1interface IAuthContext { 2 // The access token. This is what you will use for authentication against protected Web API's 3 token: string 4 // An object with all the properties encoded in the token (username, email, etc.), if the token is a JWT 5 tokenData?: TTokenData 6 // Function to trigger login. 7 // If you want to use 'state', you might want to set 'clearURL' configuration parameter to 'false'. 8 // Note that most browsers block popups by default. The library will print a warning and fallback to redirect if the popup is blocked 9 logIn: (state?: string, additionalParameters?: { [key: string]: string | boolean | number }, method: 'redirect' | 'popup' = 'redirect') => void 10 // Function to trigger logout from authentication provider. You may provide optional 'state', and 'logout_hint' values. 11 // See https://openid.net/specs/openid-connect-rpinitiated-1_0.html#RPLogout for details. 12 logOut: (state?: string, logoutHint?: string, additionalParameters?: { [key: string]: string | boolean | number }) => void 13 // Keeps any errors that occured during login, token fetching/refreshing, decoding, etc.. 14 error: string | null 15 // The idToken, if it was returned along with the access token 16 idToken?: string 17 // An object with all the properties encoded in the ID-token (username, groups, etc.) 18 idTokenData?: TTokenData 19 // If the <AuthProvider> is done fetching tokens or not. Usefull for controlling page rendering 20 loginInProgress: boolean 21}
react-oauth2-code-pkce's goal is to "just work" with any authentication provider that either
supports the OAuth2 or OpenID Connect (OIDC) standards.
However, many authentication providers are not following these standards, or have extended them.
With this in mind, if you are experiencing any problems, a good place to start is to see if the provider expects some custom parameters.
If they do, these can be injected into the different calls with these configuration options;
extraAuthParameters
extraTokenParameters
extraLogoutParameters
The <AuthProvider>
takes a config
object that supports these parameters;
1type TAuthConfig = { 2 // ID of your app at the authentication provider 3 clientId: string // Required 4 // URL for the authentication endpoint at the authentication provider 5 authorizationEndpoint: string // Required 6 // URL for the token endpoint at the authentication provider 7 tokenEndpoint: string // Required 8 // Which URL the auth provider should redirect the user to after successful authentication/login 9 redirectUri: string // Required 10 // Which scopes to request for the auth token 11 scope?: string // default: '' 12 // Optional state value. Will often make more sense to provide the state in a call to the 'logIn()' function 13 state?: string // default: null 14 // Which URL to call for logging out of the auth provider 15 logoutEndpoint?: string // default: null 16 // Which URL the auth provider should redirect the user to after logout 17 logoutRedirect?: string // default: null 18 // Optionally provide a callback function to run _before_ the 19 // user is redirected to the auth server for login 20 preLogin?: () => void // default: () => null 21 // Optionally provide a callback function to run _after_ the 22 // user has been redirected back from the auth server 23 postLogin?: () => void // default: () => null 24 // Which method to use for login. Can be either 'redirect' or 'popup' 25 // Note that most browsers block popups by default. The library will print a warning and fallback to redirect if the popup is blocked 26 loginMethod: 'redirect' | 'popup' // default: 'redirect' 27 // Optional callback function for the 'refreshTokenExpired' event. 28 // You likely want to display a message saying the user need to log in again. A page refresh is enough. 29 onRefreshTokenExpire?: (event: TRefreshTokenExpiredEvent) => void // default: undefined 30 // Whether or not to decode the access token (should be set to 'false' if the access token is not a JWT (e.g. from Github)) 31 // If `false`, 'tokenData' will be 'undefined' from the <AuthContext> 32 decodeToken?: boolean // default: true 33 // By default, the package will automatically redirect the user to the login server if not already logged in. 34 // If set to false, you need to call the "logIn()" function to log in (e.g. with a "Log in" button) 35 autoLogin?: boolean // default: true 36 // Store login state in 'localStorage' or 'sessionStorage' 37 // If set to 'session', no login state is persisted by 'react-oauth2-code-pkce` when the browser closes. 38 // NOTE: Many authentication servers will keep the client logged in by cookies. You should therefore use 39 // the logOut() function to properly log out the client. Or configure your server not to issue cookies. 40 storage?: 'local' | 'session' // default: 'local' 41 // Sets the prefix used when storing login state 42 storageKeyPrefix?: string // default: 'ROCP_' 43 // Set to false if you need to access the urlParameters sent back from the login server. 44 clearURL?: boolean // default: true 45 // Can be used to provide any non-standard parameters to the authentication request 46 extraAuthParameters?: { [key: string]: string | boolean | number } // default: null 47 // Can be used to provide any non-standard parameters to the token request 48 extraTokenParameters?: { [key: string]: string | boolean | number } // default: null 49 // Can be used to provide any non-standard parameters to the logout request 50 extraLogoutParameters?: { [key: string]: string | boolean | number } // default: null 51 // Superseded by 'extraTokenParameters' options. Will be deprecated in 2.0 52 extraAuthParams?: { [key: string]: string | boolean | number } // default: null 53 // Can be used if auth provider doesn't return access token expiration time in token response 54 tokenExpiresIn?: number // default: null 55 // Can be used if auth provider doesn't return refresh token expiration time in token response 56 refreshTokenExpiresIn?: number // default: null 57 // Defines the expiration strategy for the refresh token. 58 // - 'renewable': The refresh token's expiration time is renewed each time it is used, getting a new validity period. 59 // - 'absolute': The refresh token's expiration time is fixed from its initial issuance and does not change, regardless of how many times it is used. 60 refreshTokenExpiryStrategy?: 'renewable' | 'absolute' // default: renewable 61 // Whether or not to post 'scope' when refreshing the access token 62 refreshWithScope?: boolean // default: true 63 // Controls whether browser credentials (cookies, TLS client certificates, or authentication headers containing a username and password) are sent when requesting tokens. 64 // Warning: Including browser credentials deviates from the standard protocol and can introduce unforeseen security issues. Only set this to 'include' if you know what 65 // you are doing and CSRF protection is present. Setting this to 'include' is required when the token endpoint requires client certificate authentication, but likely is 66 // not needed in any other case. Use with caution. 67 tokenRequestCredentials?: 'same-origin'|'include'|'omit' // default: 'same-origin' 68} 69
A session expire happens when the refresh_token
is no longer valid and can't be used to fetch a new valid access_token
.
This is governed by the expires_in
, and refresh_expires_in | refresh_token_expires_in
, in the token response.
If the response does not contain these values, the library assumes a quite conservative value.
You should configure your IDP (Identity Provider) to send these, but if that is not possible, you can set them explicitly
with the config parameters tokenExpiresIn
and refreshTokenExpiresIn
.
The library's main componet AuthProvider
is client side only. Meaning it must be rendered in a web browser, and can not be pre-rendered server-side (which is default in newer versions of NextJS and similar frameworks).
This can be solved by marking the module with use client
and importing the component in the client only ("ssr": false
).
1'use client' 2import {useContext} from "react"; 3import dynamic from 'next/dynamic' 4import {TAuthConfig,TRefreshTokenExpiredEvent, AuthContext} from 'react-oauth2-code-pkce' 5 6const AuthProvider = dynamic( 7 ()=> import("react-oauth2-code-pkce") 8 .then((mod) => mod.AuthProvider), 9 {ssr: false} 10) 11 12const authConfig: TAuthConfig = {...for you to fill inn} 13 14export default function Authenticated() { 15 (<AuthProvider authConfig={authConfig}> 16 <LoginInfo/> 17 </AuthProvider>) 18}
Bad authorization state...
This is most likely to happen if the authentication at the identity provider got aborted in some way.
You might also see the error Expected to find a '?code=' parameter in the URL by now. Did the authentication get aborted or interrupted?
in the console.
First of all, you should handle any errors the library throws. Usually, hinting at the user reload the page is enough.
Some known causes for this is that instead of logging in at the auth provider, the user "Registers" or "Reset password" or something similar instead. Any such functions should be handled outside of this library, with separate buttons/links than the "Log in" button.
?code
, no token request is madeIf you are using libraries that intercept any fetch()
-requests made. For example @tanstack/react-query
. That can cause
issues for the AuthProviders token fetching. This can be solved by not wrapping the <AuthProvider>
in any such library.
This could also happen if some routes in your app are not wrapped by the <AuthProvider>
.
This will happen if you haven't provided a callback-function for the onRefreshTokenExpire
config parameter, and the refresh token expires.
You probably want to implement some kind of "alert/message/banner", saying that the session has expired and that the user needs to log in again.
Either by refreshing the page, or clicking a "Log in" button.
src/index.js
with config from your authorization server and application$ yarn install
$ yarn start
You are most welcome to create issues and pull requests :)
No vulnerabilities found.
No security vulnerabilities found.