Giter Site home page Giter Site logo

jetbridge / axios-jwt Goto Github PK

View Code? Open in Web Editor NEW
115.0 10.0 30.0 2.06 MB

Store, transmit, refresh JWT authentication tokens for axios

Home Page: https://www.npmjs.com/package/axios-jwt/

TypeScript 99.03% JavaScript 0.97%
axios interceptor jwt typescript

axios-jwt's People

Contributors

abereghici avatar adamszeptycki avatar aurarius1 avatar caioaugustoo avatar dependabot[bot] avatar digitalkaoz avatar dizzzmas avatar greenyas avatar moshfrid avatar mvanroon avatar pwfraley avatar rawnly avatar revmischa avatar splurgebudget avatar yohantoledo avatar ziplokk1 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

axios-jwt's Issues

Question

I have a question, by default the localStorage Storage uses auth-tokens-${process.env.NODE_ENV} as a name for the local storage.

My Question:
What is the correct way to override this?

Thanks

Allow a different storage.

Hello, I would like to store my credentials inside a cookie. I need them available for SSR reasons. Having the ability to specify a custom storage would be nice.

It could be done extending the existing Storage interface and adding it to the config object.

How to deal with refresh tokens that are expired?

Thanks for creating this cool library!

I was wondering how to deal with expired refresh tokens? Currently, there seems to be no way to handle this. Is it possible to specify a force-logout URL in case the refresh fails with a 401 or 403?

Thanks!

Return interceptor

I suggest adding a return to the end of useAuthTokenInterceptor so that the interceptor is returned, so that it may later be ejected if needed.

return axios.interceptors.request.use(authTokenInterceptor(config))

Support rotating refresh tokens

Some backends also rotate refresh tokens when exchanging your access token for a fresh one. This means that the backend will present a new refresh token in addition to the new access token.

I'll create a PR somewhere this weekend to support this.

StorageType undefined outside the interceptor?

I'm a back-end coder, so go easy on me here, as this may be outright pilot error.

Setting up and using authTokenInterceptor looks to be working just fine, thanks for that - but, when trying to follow the examples in the README, to call e.g. setAuthTokens, isLoggedIn, etc outside the context of the interceptor, it seems like StorageProxy.Storage is just returning null, so those calls simply do nothing.

What am I missing here? If one calls setAuthTokens such as in the Login/Logout example, where is the storage actually being set?

I'm happy to give more detail or code snips, etc, as needed.

Publish correct build to NPM

npmjs.com shows version 1.0.4 of this plugin: https://www.npmjs.com/package/axios-jwt

It seems to be quite different from master in this repo. In that version, TokenRefreshRequest returns Promise<string> and does not seem to ever update the refresh token.

Looking at master here, the refresh function returns Promise<IAuthTokens>. Interestingly enough, package.json declares this to be version 1.0.1.

Uncaught TypeError: (0 , ms_1.default) is not a function

Appears I am missing the "ms" dependency, installing it doesn't resolve the issue however

Uncaught TypeError: (0 , ms_1.default) is not a function
at authTokenInterceptor (authTokenInterceptor. ts:178:1)
at app lyAuthTokenInterceptor (applyAuthTokenInterceptor.ts:16:1)
at ./src/api/auth.ts (auth.ts:43:1

Non-typescript usage examples?

I'm trying to set up JWT tokens for my axios-powered API handler. I want it to automatically refresh tokens if there's an issue without forcing a retry on the request, as well. Seems well and good.

I found this library and am working to implement it, but the examples seem to be TypeScript-based, but I'm not using TypeScript. Would be helpful to have examples for regular JS.

No requests are made if applyAuthTokenInterceptor called

Hello, im using React 18 and axios 1.4.0
This is how I define the axios instance (following the tutorial)

const BASE_URL = 'http://localhost:8080/api'

// 1. Create an axios instance that you wish to apply the interceptor to
export const apiAuthInstance = axios.create({ baseURL: BASE_URL })

// 2. Define token refresh function.
const requestRefresh: TokenRefreshRequest = async (refreshToken: string): Promise<IAuthTokens | string> => {
 
  const response = await axios.post(`${BASE_URL}/auth/refresh_token`, { token: refreshToken })
  return response.data.access_token
}

// 3. Add interceptor to your axios instance
applyAuthTokenInterceptor(apiAuthInstance, { requestRefresh })

// If applyAuthTokenInterceptor is applied, then I cant make any api calls at all
// Here "/asd" wont be called, or any other place it just doesnt make the call. 
// What am I doing wrong?
apiAuthInstance.post("/asd")

not setting header

Added all code per the read me into a REACT (non-type script project)

Here is my code:

import { applyAuthTokenInterceptor } from 'axios-jwt';
import axios from 'axios';

const BASE_URL = 'http://localhost:5000/api/';

const axiosInstance = axios.create({ baseURL: BASE_URL });

const requestRefresh = (refresh) => {
  // Notice that this is the global axios instance, not the axiosInstance!  <-- important
  return axios.post(`${BASE_URL}/auth/refreshtoken`, { refresh }).then((response) => response.data.token);
};

applyAuthTokenInterceptor(axiosInstance, { requestRefresh }); // Notice that this uses the axiosInstance instance.  <-- important

export default axiosInstance;

Dependencies:

  "dependencies": {
    "@testing-library/jest-dom": "^5.17.0",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "axios": "^1.6.2",
    "axios-jwt": "^3.0.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.20.1",
    "react-scripts": "5.0.1",
    "web-vitals": "^2.1.4"
  },

localstorage is not defined

It seem that the storage abstraction, specifically exporting localstorage in the storage.ts file, is breaking server-side code.

image

undefined window and Synchronous isLoggedIn

For some reason, the new swappable storage interface has caused isLoggedIn to not excecute properly on initial page load. For example, in my app im using it to set the ui state for logged in vs not logged in users and now it returns false on page load (onmount useeffect) and true only later, rendering the wrong ui state.

Furthermore, when trying to build the app, getBrowserLocalStorage is causing a ReferenceError: window is not defined t be thrown

'getStorage' does not exist in type 'IAuthTokenInterceptorConfig'

Seems like there's a problem with types:

My test code

import axios from 'axios'
import { applyAuthTokenInterceptor } from 'axios-jwt'

const api = axios.create()

applyAuthTokenInterceptor(api, { getStorage: () => window.sessionStorage })

Exception

src/index.ts(6,34): error TS2345: Argument of type '{ getStorage: () => Storage; }' is not assignable to parameter of type 'IAuthTokenInterceptorConfig'.
  Object literal may only specify known properties, and 'getStorage' does not exist in type 'IAuthTokenInterceptorConfig'.

Error: error occured in dts build
    at Worker.<anonymous> (/Users/federicovitale/Developer/projects/new-proj/node_modules/.pnpm/[email protected][email protected]/node_modules/tsup/dist/index.js:2181:26)
    at Worker.emit (node:events:527:28)
    at MessagePort.<anonymous> (node:internal/worker:232:53)
    at MessagePort.[nodejs.internal.kHybridDispatch] (node:internal/event_target:643:20)
    at MessagePort.exports.emitMessage (node:internal/per_context/messageport:23:28)
Error: Failed to compile. Check the logs above.
    at error (/Users/federicovitale/Developer/projects/new-proj/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/shared/rollup.js:198:30)
    at throwPluginError (/Users/federicovitale/Developer/projects/new-proj/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/shared/rollup.js:21718:12)
    at Object.error (/Users/federicovitale/Developer/projects/new-proj/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/shared/rollup.js:22672:20)
    at Object.error (/Users/federicovitale/Developer/projects/new-proj/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/shared/rollup.js:21895:42)
    at Object.transform (/Users/federicovitale/Developer/projects/new-proj/node_modules/.pnpm/[email protected][email protected]/node_modules/tsup/dist/rollup.js:7217:20)
    at /Users/federicovitale/Developer/projects/new-proj/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/shared/rollup.js:22879:40
[TS-PACKAGE] DTS Build error
 ELIFECYCLE  Command failed with exit code 1.

[email protected]

> npm update
npm error code ERESOLVE
npm error ERESOLVE could not resolve
npm error
npm error While resolving: web@0.2.0
npm error Found: react@18.3.1
npm error node_modules/react
npm error   react@"^18.2.0" from the root project
npm error   peer react@"^18.0.0" from @testing-library/react@14.3.1
npm error   node_modules/@testing-library/react
npm error     dev @testing-library/react@"^14.1.2" from the root project
npm error   1 more (react-dom)
npm error
npm error Could not resolve dependency:
npm error axios-jwt@"^4.0.0" from the root project
npm error
npm error Conflicting peer dependency: react@18.2.0
npm error node_modules/react
npm error   peer react@"18.2.0" from react-native@0.74.1
npm error   node_modules/react-native
npm error     peer react-native@"^0.0.0-0 || >=0.60 <1.0" from @react-native-async-storage/async-storage@1.23.1
npm error     node_modules/@react-native-async-storage/async-storage
npm error       peerOptional @react-native-async-storage/async-storage@"^1.15.17" from axios-jwt@4.0.2
npm error       node_modules/axios-jwt
npm error         axios-jwt@"^4.0.0" from the root project
npm error
npm error Fix the upstream dependency conflict, or retry
npm error this command with --force or --legacy-peer-deps
npm error to accept an incorrect (and potentially broken) dependency resolution.
npm error
npm error
npm error For a full report see:

Request without the interceptor

I would like to know if there is a way to not use the interceptor in some calls, sometimes I have call which do not require the tokens.

getAccessToken() returns undefined

Hi,
the getAccessToken (or isLoggedIn) returns undefined if the authTokenInterceptor has not been applied yet. This is of course because of the missing applyStorage call, but the library doesn't export this at root level (import {applyStorage} from 'axios-jwt' doesn't work). Rather one has to import from the dist folder directly.

Should I create a pull request that just adds the export in the index.ts file?

Kind regards
Lukas

Retry failed request after RefreshToken

it would be nice to have a general retry handler aswell:

const onOk = (response) => response;
const onError = (error) => {
	// Return any error which is not due to authentication back to the calling service
	if (error && error.response && error.response.status !== 401) {
		return Promise.reject(error);
	}

	const config = error.config;

	// Logout user if token refresh didn't work or user is disabled
	if (error.config.url.endsWith("auth/refresh")) {
		logout();
		return Promise.reject(error);
	}

	// Try request again with new token
	return new Promise((resolve, reject) => {
		requestRefresh().then((response) => {
			setAuthTokens(response.data)
			return http.request(config).then((response) => resolve(response));
		}).catch((e) => {
			clearAuthTokens()
			reject(e)
		})
	});
};

http.interceptors.response.use(onOk, onError);

[React Native] Not working

Unable to resolve module `stream` from `node_modules/jws/lib/sign-stream.js`: stream could not be found within the project

Bug in README.md JavaScript Version

In the README.md you give examples for the JavaScript Version,

in there you call the setAuthTokens and clearAuthTokens, this throws an error unknown funtion, because you are not importing those functions.

So the Import in the JavaScript Version should be changed from:

import { applyAuthTokenInterceptor } from 'axios-jwt';

To:

import { applyAuthTokenInterceptor, setAuthTokens, clearAuthTokens } from 'axios-jwt';

Breaks on webpack 5

Apparently it uses node.js modules under the hood which are no longer bundled by webpack 5.


After going through the source code I believe the refresh strategy is not the best. Instead of checking the expiration time of the token on each request (parsing jwt is time consuming) one should check the response status for 401 status code or call a user provided callback to check if the token should be refreshed. Initiate a refresh if any condition is met. At the same time queue all the outgoing requests and also queue any request that was fired prior to the refresh and returned with 401 status.

Feature Request: Allow prepended string for token names

I have an application with two sets of tokens for two sets of users in the same application and would like to prepend a string to the stored token so they are distinct. I need the lifecycle on each set of access and refresh token to be distinct.

[React Native] Not working

Unable to resolve module `stream` from `node_modules/jws/lib/sign-stream.js`: stream could not be found within the project

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.