bitysa / oauth2-auth-code-pkce Goto Github PK
View Code? Open in Web Editor NEWAn OAuth 2.0 client that ONLY supports the Authorization Code flow with PKCE support.
License: Apache License 2.0
An OAuth 2.0 client that ONLY supports the Authorization Code flow with PKCE support.
License: Apache License 2.0
First, thank you for this library! It is the finest I found, the code is nice, sweet and to the point. It is easy to understand and I hope it stays this way. I appreciate you only support auth_flow with PKCE on the client side. It makes it much easier to grok because the code is so targeted.
Second, I think we should update the documentation slightly - I would do a PR but I think it's so trivial you can just include it in your next update. The documentation for Usage should include a step of npm run build
prior to instructing npm run serve:tests
.
Also, in the tests/panel.html, the redirectUrl uses port 8000 instead of 8080.
Most importantly, for your incoming users I'd like to say that yes this does work with AWS cognito and is a sweet, sweet relief from having to use the amplify garbage and this is considerably less complex than amazon-cognito-auth-js
. One final note, among the universe of incredibly detailed things you need to know about getting cognito working - You need to use a client id that DOES NOT have a secret. This means uncheck generate secret when you are creating the client (or GenerateSecret: false in cloudformation). Also even though AWS documentation says
The user pool client makes requests to this endpoint directly and not through the system browser.
This is NOT true when using Auth Flow w/ PKCE, and this library is exactly for that and will suit your needs perfectly.
Thank you @BitySA
Would you consider exposing the id_token too?
(That may be an AWS Cognito specific thing? - but very desireable!)
It looks like some OAuth Saas providers url encode characters in the state query param which shouldn't be encoded. For example, it encodes ~
as &7E
.
Because of that url encoding, this check fails.
It's easily solvable by wrapping the return value in a decodeURI
call, but I'm not sure if that's the best solution.
In a OAuth2 authorization code flow the state parameter is a way to keep state across browser redirects. You can use it to inject some data into the flow at the start, and then recover that data at the end. This package uses this feature to increase security by injecting a random string at the start and checking that it is unchanged at the end. That's awesome. However, the user may also want to add some of their own data to the state. Currently this package offers no mechanism to do that.
Allow the user to add a additionalState
function that returns a string to the configuration and just concatenate its (url encoded) return value to the randomly generated state in fetchAuthorizationCode
. Then, in isReturningFromAuthServer
after the state has been verified, extract the additional state, url decode it, and assign it to this.state.additional
. Finally add a public getter getAdditionalState
for the user to retrieve this state.
Note that this proposal is backward compatible. Also, if I'm reasonably confident that a PR along these lines (or whatever alternative approach) will actually be accepted I will probably create one.
I think the most common use case for this would probably be adding a redirect url to the state because it's not always practical or even possible to configure de OAuth server to allow all the possible redirect urls you might need.
I get an error "AADSTS900561: The endpoint only accepts POST, OPTIONS requests. Received a GET request." on the code request.
Should this library expose a logout / or reset state API?
Hi there!
We're experimenting with the "new" OAuth2 Auth code + PKCE flow in SPA apps with different OAuth SaaS providers. We noticed that Okta was giving verification errors. After inspecting, it seems that the verifiers generated by this library are longer than the max length of 128 characters (.length returns 171). Limiting the generated verifier to the the max length did fix the error we were getting.
I'm not 100% sure what the cause of this is since I'm not super familiar with this kind of code, but maybe the Okta library or this PKCE verifier + challenge generator library might provide more insights. My guess is that btoa
might have something to do with it ๐ .
Local Storage is only really suitable in very secure environments as the tokens will persist even after a browser has been closed.
SessionStorage and Cookie Storage provide better backend choices for applications that intend to be deployed to less secure environments.
Would you consider providing a config option to allow the consumer to select which storage backend is used?
You could include this library:
https://github.com/jherax/proxy-storage
or simply use it for inspiration if you wanted to keep this library as lean as it currently is.
Recently I wanted to use this library but failed. The structure of the code made it impossible to adapt it in a way that would fit my application. So after some time of trial and error I decided to copy the library and change the code with these goals:
async
/await
instead of then()
Are you interested in integrating such changes in general into your repository? Personally I think, the library would benefit from it, but well, we all do like our own code, don't we? ;-) If so, I could make a fork and drop my code in so you can have a look. If you rather not have someone touch basically all lines of your code, well, I can make it available elsewhere ๐คท
Making multiple fetch calls using OAuth2AuthCodePKCE.decorateFetchHTTPClient(fetch)
while the access token is expired will result in multiple token refresh calls. Unfortunately this causes issues such as invalid_grant
error responses and potentially even rate limiting. For example, gitlab.com rate limits this particular API call to 10 requests/minute.
Here's how I worked around the issue, but it would be ideal to implement this in your library instead:
export const createGitlabOAuth = () => {
let expiryPromise;
let invalidGrantPromise;
return new OAuth2AuthCodePKCE({
authorizationUrl: 'https://gitlab.com/oauth/authorize',
tokenUrl: 'https://gitlab.com/oauth/token',
clientId: process.env.REACT_APP_GITLAB_CLIENT_ID,
redirectUrl: window.location.origin,
scopes: ['api'],
extraAuthorizationParams: {
clientSecret: process.env.REACT_APP_GITLAB_SECRET,
},
onAccessTokenExpiry: async (refreshToken) => {
if (!expiryPromise) {
expiryPromise = refreshToken();
}
const result = await expiryPromise;
expiryPromise = undefined;
return result;
},
onInvalidGrant: async (refreshAuthCodeOrToken) => {
if (!invalidGrantPromise) {
invalidGrantPromise = refreshAuthCodeOrToken();
}
// This is a void promise, so don't need to return the result. Refer to the TypeScript source
// of OAuth2AuthCodePKCE. Types are great.
await invalidGrantPromise;
invalidGrantPromise = undefined;
},
});
};
Note: the onAccessTokenExpiry
workaround was the important part for the specific scenario I encountered, but I think it makes sense to do in onInvalidGrant
too.
As currently written, removeQueryParams
messes up the URL when there is no hash portion. The .split('#')
will make hashUrlPart undefined when there is no hash, but the code doesn't check for this and instead always returns ${urlPart}#${hashUrlPart}
. The result is an erroneous hash of #undefined
for such cases. Should be an easy fix.
I found this client by searching npmjs.com. I noticed the link to the repository was missing which made this github page hard to find (it's not indexed on search engines yet). Adding a "repository" field to the package.json file should add that link to the Github repository.
If extraRefreshParams
are provided, then the grant_type
, refresh_token
, and client_id
are no longer sent.
Permalink to bug in master:
oauth2-auth-code-pkce/index.ts
Lines 388 to 390 in 89f3893
I think this should actually be (untested):
if (extraRefreshParams) {
body = `${body}&${OAuth2AuthCodePKCE.objectToQueryString(extraRefreshParams)}`
}
Hello,
Thank you for writing oauth2-auth-code-pkce! I noticed that the project is currently under an AGPLv3 license.
I was wondering if you could consider changing the license to a more liberal MIT or Apache v2? This would let the library be used as a library more easily in many projects.
If not, no problem, licensing is obviously your choice.
Thanks!
Paul
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.