jetbridge / axios-jwt Goto Github PK
View Code? Open in Web Editor NEWStore, transmit, refresh JWT authentication tokens for axios
Home Page: https://www.npmjs.com/package/axios-jwt/
Store, transmit, refresh JWT authentication tokens for axios
Home Page: https://www.npmjs.com/package/axios-jwt/
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
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.
Currently this breaks on axios > 0.21.4, would be great to be able to upgrade
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!
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))
The token should be added in a httponly cookie and only the refresh token should be stored.
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.
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.
When i try refresh token, i get infinity loop with Promise
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.
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
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.
package.json Currently enforces "@react-native-async-storage/async-storage": "1.15.17", but that is now conflicting with other packages. Can we update to ^1.15.17?
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")
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"
},
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
Seems like there's a problem with types:
import axios from 'axios'
import { applyAuthTokenInterceptor } from 'axios-jwt'
const api = axios.create()
applyAuthTokenInterceptor(api, { getStorage: () => window.sessionStorage })
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.
> 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:
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.
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
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);
Unable to resolve module `stream` from `node_modules/jws/lib/sign-stream.js`: stream could not be found within the project
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';
Hi Again! Fresh install of 4.0.1 throws an error because package.json says to look in /dist/index but its not there
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.
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.
Unable to resolve module `stream` from `node_modules/jws/lib/sign-stream.js`: stream could not be found within the project
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.