GithubHelp home page GithubHelp logo

girder / girder-oauth-client Goto Github PK

View Code? Open in Web Editor NEW
6.0 8.0 1.0 677 KB

A TypeScript library for performing OAuth login to a Girder 4 (Django) server.

License: Apache License 2.0

HTML 3.04% JavaScript 7.18% TypeScript 89.78%
girder-4

girder-oauth-client's Introduction

girder-oauth-client

npm (scoped)

A TypeScript library for performing OAuth login to a Girder 4 (Django) server.

Description

This provides support for authenticating with Girder 4 servers, using the OAuth2.0 Authorization Code Grant with PKCE flow.

Usage

  • Install the library:

    yarn add @girder/oauth-client

    or if you're using npm:

    npm install @girder/oauth-client
  • Instantiate an OauthClient with your application-specific configuration:

    import OauthClient from '@girder/oauth-client';
    
    const oauthClient = new OauthClient(
      new URL(process.env.OAUTH_API_ROOT), // e.g. 'http://localhost:8000/oauth/'
      process.env.OAUTH_CLIENT_ID, // e.g. 'Qir0Aq7AKIsAkMDLQe9MEfORbHEBKsViNhAKJf1A'
    );
  • Call redirectToLogin when it's time to start a login flow:

    document.querySelector('#sign-in-link').addEventListener('click', (event) => {
      event.preventDefault();
      oauthClient.redirectToLogin();
      // This will redirect away from the current page
    });
  • At the start of every page load, unconditionally call maybeRestoreLogin, to attempt to restore a login state; this will no-op if no login is present. Afterwards, get and store HTTP headers for authentication from authHeaders.

    let authHeaders;
    oauthClient.maybeRestoreLogin()
      .then(() => {
        authHeaders = oauthClient.authHeaders;
      });

    or, if using ES6 and async/await:

    await oauthClient.maybeRestoreLogin();
    let { authHeaders } = client;
  • Include these headers with every Ajax API request:

    fetch('http://localhost:8000/api/files', {
      headers: authHeaders,
    });
  • The login state will persist across page refreshes. Call logout to clear any active login:

    document.querySelector('#sign-out-link').addEventListener('click', (event) => {
      event.preventDefault();
      oauthClient.logout()
        .then(() => {
          authHeaders = oauthClient.authHeaders;
        });
    });

Example app

This repository comes bundled with an example application. Run it with:

git clone https://github.com/girder/girder-oauth-client.git
yarn install
yarn build
cd example
yarn install
yarn serve
# Visit http://localhost:1234/

Development

To develop the library using the example app:

# From the root of the repository
yarn link
yarn install
yarn watch

In another terminal:

# From the root of the repository
cd example
yarn link '@girder/oauth-client'
yarn install
yarn serve

girder-oauth-client's People

Contributors

brianhelba avatar danlamanna avatar zachmullen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Forkers

subdavis

girder-oauth-client's Issues

More informative error handling

If the authorizationServerBaseUrl argument passed to OauthClient is not a complete URL, no exception will be thrown until the openid RedirectRequestHandler attempts to build a new URL(...) object out of it. Sadly, the error is swallowed by this try/catch:

try {
this.token = await this.oauthFacade.finishLogin();
} catch {
// Most likely, there is no pending Authorization flow.
// Possibly, there is an Authorization failure, which will be emitted to the
// console, but doesn't need to be fatal, since this can just proceed with no token.
}

Either an earlier check for this malformed user input or a more specific catch would have saved me a few hours of debugging.

Expired/revoked tokens are not cleared

If a token ever expires, I don't see any code that would handle gracefully cleaning up and logging out. OauthClient will still load the expired token and act as if it is valid. An end user would have to recognize that requests to the backend were not authenticating, and then manually log out of the site and log back in again.

As the symptoms of an expired or revoked token are implementation specific, this might be a problem that has to be solved individually by each consumer of this library.

Abort login flow if CORS error is encountered

If CORS is misconfigured on the server, the authorization flow can still succeed. However, when maybeRestoreLogin is called, it performs an XHR call to get a token from the API server, which fails because of CORS. This error is interpreted as meaning that the user is not authenticated, so the browser is redirected to the start of the OAuth flow again, creating an infinite loop.

It would be nice if the OAuth client could distinguish between a 401 and a CORS error and abort the login flow with an informative error if a CORS error is encountered.

attn @zachmullen

Code and state are not removed from the URL on auth completion

Library version: 0.8.0

After successfully logging in, the code and state parameters are not stripped from the URL. This is occurring when using history-based routing, and I'm not sure if it's occurring with hash-based routing. Example:

http://localhost:3000/?code=FgGYjo14HIgV4K8QszJN5HLdU3LbMy&state=vsORAETN0z

Determine appropriate build settings

What ES version should we target during build? Most consumers will not transpile this library, so we want something that should work in all target environments (which will always be a browser, never Node) and will be interpretable by typical bundler tools.

There are two major decision points:

  • Import type
    • Ideally, we can ship ES-module imports (rather than CommonJS)
  • General language version
    • Perhaps it's a good idea to transpile away extremely new language features

Useful references:
https://www.typescriptlang.org/docs/handbook/compiler-options.html
https://stackoverflow.com/questions/50986494/what-does-the-typescript-lib-option-really-do
https://stackoverflow.com/questions/48378495/recommended-typescript-config-for-node-8

Make OauthClient.authHeaders always return a key

By returning something like {Authorization: null} even when logged out, it should be more clear to downstreams that the header's value is "owned" by the OauthClient, and should be included opaquely with all Ajax requests.

Whether is this feasible depends on how the major Ajax libraries support setting null values for headers.

Query params are not cleared if token already exists

The code path that deletes code and state from the query parameters only runs when the token does not exist in local storage. When the login flow completes, but a token is already saved in local storage, the saved token is used and the query parameters are completely ignored.

The only reasonable way to encounter this behavior is to somehow start two simultaneous login flows, then complete them sequentially. Upon redirecting back to the client, the second login flow will load the token from the first flow and ignore the query parameters, putting the URL string into a slightly dubious state.
It can also happen if a user somehow starts the login flow again while already logged in, but being able to do that probably indicates a bug somewhere else.

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.