GithubHelp home page GithubHelp logo

bitysa / oauth2-auth-code-pkce Goto Github PK

View Code? Open in Web Editor NEW
51.0 3.0 18.0 197 KB

An OAuth 2.0 client that ONLY supports the Authorization Code flow with PKCE support.

License: Apache License 2.0

TypeScript 93.32% HTML 6.68%
oauth oauth2 pkce cognito

oauth2-auth-code-pkce's People

Contributors

florv avatar lf94 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

Watchers

 avatar  avatar  avatar

oauth2-auth-code-pkce's Issues

Doc issues and a few cognito notes.

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

state param url encoding problem

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.

Add/recover custom data to/from the state

Introduction

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.

Proposal

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.

Use case

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.

POST method not supported

I get an error "AADSTS900561: The endpoint only accepts POST, OPTIONS requests. Received a GET request." on the code request.

Generated verifier length

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 ๐Ÿ˜„ .

Support Cookie Storage and/or Session Storage

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.

Rewrite

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:

  • break it into smaller pieces so that
    • it is easier to maintain
    • it is possible to change single aspects
  • remove duplicate code
  • make the process as transparent as possible with as little magic as possible
  • keep the API mostly as it is
  • use 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 ๐Ÿคท

Bug: prevent concurrent access token refresh attempts

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.

removeQueryParams can't handle empty hash

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.

Add a "repository" key to the package.json file

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.

Bug: mishandled `extraRefreshParams`

If extraRefreshParams are provided, then the grant_type, refresh_token, and client_id are no longer sent.

Permalink to bug in master:

if (extraRefreshParams) {
body = `${url}&${OAuth2AuthCodePKCE.objectToQueryString(extraRefreshParams)}`
}

I think this should actually be (untested):

 if (extraRefreshParams) { 
   body = `${body}&${OAuth2AuthCodePKCE.objectToQueryString(extraRefreshParams)}` 
 } 

License Q

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

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.