Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
f2110e1
implementing the pkce flow, wip
TaSiya Oct 9, 2019
2e35406
conditional authorization, added encoding and hashing functions, wip
TaSiya Oct 10, 2019
e6a3b50
testing the render props and context api, wip
TaSiya Oct 11, 2019
fe98404
changed the version
TaSiya Oct 14, 2019
0ce64c1
added change to use new files
TaSiya Oct 14, 2019
22aeba8
created the auth context
TaSiya Oct 14, 2019
57e4895
working on adding the authentication logic, wip
TaSiya Oct 14, 2019
d8aba63
remoed unsed code
TaSiya Oct 14, 2019
a9b8b20
added a hashing functions
TaSiya Oct 14, 2019
4564372
trying to get the code from the url
TaSiya Oct 14, 2019
1bf34b8
removed the useless code
TaSiya Oct 15, 2019
14debaf
removed/ renamed the old version files, added a code manager componen…
TaSiya Oct 15, 2019
7279b59
name changed
TaSiya Oct 15, 2019
b5a7172
changed the structure of the authentication component because I reali…
TaSiya Oct 15, 2019
353f719
changed the file structure and combined the test client with the reac…
TaSiya Oct 16, 2019
025a4ef
changed to extract the code from the url, hacked needs to be fixed
TaSiya Oct 17, 2019
9ea2e4a
put actual client with its secret
TaSiya Oct 17, 2019
07b43dd
moved the the file
TaSiya Oct 17, 2019
3da054c
added validation of the props, WIP
TaSiya Oct 17, 2019
1f5f86a
not using the code manager component, updating the authentication com…
TaSiya Oct 17, 2019
5079bb0
mamaned to get the token from the provider, wip
TaSiya Oct 17, 2019
f9d30db
updated the readme for the new version, wip
TaSiya Oct 18, 2019
9192cee
removed old files, wip
TaSiya Oct 18, 2019
3740afa
changed from localStorage to sessionStorage
TaSiya Oct 22, 2019
b0f2599
removed old code and logs
TaSiya Oct 22, 2019
4d88df7
removed logs and empty spcaes
TaSiya Oct 22, 2019
bfb764f
fixed the build to be /lib
TaSiya Oct 30, 2019
90f8c2f
removed redirect
TaSiya Oct 30, 2019
f10f5dd
moved files to correct places
TaSiya Oct 30, 2019
dbc0fc9
Experimentally implementing auth state via hooks
Chris927 Nov 16, 2019
df63704
Upgraded dependencies
Chris927 Nov 16, 2019
48d08fe
Skeletal design, may work, wip
Chris927 Nov 16, 2019
17c2cce
Replaced 'crypto' reference, towards functioning example, wip
Chris927 Nov 16, 2019
db7dec0
Added helper functions for code and verifier, but component structure…
Chris927 Nov 16, 2019
2f0d047
Changed to use React context internal to factory function only, wip
Chris927 Nov 16, 2019
9636459
Moved code and verifier logic to AuthContext, seems the right structu…
Chris927 Nov 16, 2019
c12b015
Trying to fetch token, but hitting cors issue, wip
Chris927 Nov 16, 2019
35e7a5e
Fetching token now functional, token management is wip
Chris927 Nov 17, 2019
89586a3
Added 'useToken' hook, demo
Chris927 Nov 17, 2019
cea85bd
Removed old code, maybe ready to publish under 'react-pkce'
Chris927 Nov 17, 2019
45304ac
npm, ignore /public next time
Chris927 Nov 17, 2019
e7b2a36
mention that this package has 0 dependencies
Chris927 Nov 17, 2019
2dfc945
0.9.1
Chris927 Nov 17, 2019
3275e1f
Changed logic when to authenticate, may fix 'hang' issue when either …
Chris927 Nov 17, 2019
a854302
0.9.2
Chris927 Nov 17, 2019
d4725eb
Adjust how we history.replaceState
Chris927 Nov 17, 2019
c0182de
0.9.3
Chris927 Nov 17, 2019
bf8dbea
Changed how we clear verifier key from storage, should fix refresh issue
Chris927 Nov 17, 2019
404a62e
0.9.4
Chris927 Nov 17, 2019
5999094
Added link to live demo
Chris927 Nov 17, 2019
70a7ee2
Moved functions to their own files, made busy indicator configurable
Chris927 Nov 17, 2019
2c4afa7
0.9.5
Chris927 Nov 17, 2019
5336539
Updated README to clarify how to "export", documented optional config…
Chris927 Nov 19, 2019
43360ea
0.9.6
Chris927 Nov 19, 2019
127bfe0
Fix link to test app, source link
Chris927 Nov 19, 2019
baad8f7
0.9.7
Chris927 Nov 19, 2019
ffef968
using local provider
TaSiya Apr 14, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/src
/sample
/public
135 changes: 94 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,74 +1,127 @@
# What is It?

A simple React component and higher order function to facilitate authentication
via U5-Auth (or rather, any OAuth2 provider).
This zero-dependency package enables [React](https://reactjs.org/) applications
to use an OAuth2 provider for
authentication. The OAuth2 provider must support the
[PKCE Spec](https://tools.ietf.org/html/rfc7636).

(TODO: Links to resources that explain why this is a good idea / better than
using the implicit flow.)

Check the [live demo](https://uber5.github.io/react-pkce-sample/)
([source](https://github.com/Uber5/react-pkce-sample)).
When prompted to login, you can signup with email (use link at the bottom of the form).

# Prerequisites

* The provider url, e.g. `https://login.u5auth.com`.
* OAuth2 client credentials, where the client is allowed to use the
[implicit flow](https://tools.ietf.org/html/rfc6749#section-1.3.2).
* A [React]() application, which is supposed to be secured via OAuth2 (or
* The provider url, e.g. `https://login.u5auth.com`
* OAuth2 client credentials (client id and secret),
where the client is allowed to use the
[Authorization code grant](https://tools.ietf.org/html/rfc6749#section-4.1).
* A React application, which is supposed to be secured via OAuth2 (or
rather, needs an `access_token` to authenticate e.g. calls to APIs).

# How

## Setup
## Install

```
npm i react-pkce
```

Client details need to be specified via the `AuthContext` component. The `AuthContext` must wrap any component that needs authentication, so the `AuthContext` is probably best placed high up in the component tree (maybe just above the router, if you use one):
## Use

First, import the `AuthContext` component:
First, create an auth context (and related things):

```javascript
import { AuthContext } from 'react-u5auth'
```js
const clientId = "8cb4904ae5581ecc2b3a1774"
const clientSecret = "b683283462070edbac15a8fdab751ada0f501ab48a5f06aa20aee3be24eac9cc"
const provider = "https://authenticate.u5auth.com"

const {AuthContext, Authenticated, useToken} = createAuthContext({
clientId,
clientSecret,
provider
})
```

Then, wrap your component(s):
You probably need those in other files, so you may want to `export` them:

```react
<AuthContext clientId={"123"} provider={"https://my-provider.com"}>
<Router history={browserHistory}>
// ...
</Router>
</AuthContext>
```js
export { AuthContext, Authenticated, useToken }
```

## Protecting Components

Now, the higher-order function `authenticated` can be used to ensure a valid `access_token` whenever the component gets rendered:
Next, use the `AuthContext` to wrap anything that may require
an authenticated user / an access token for an authenticated user.
Typically, you would wrap the whole app inside of an `AuthContext`:

```js
import { authenticated } from 'react-u5auth'
function App() {
return (
<AuthContext>
// ... all my other components, e.g. router, pages, etc.
</AuthContext>
)
}
```

Thirdly, when implementing a component that requires an authenticated user,
wrap anything you want to protect from the public in an `Authenticated`
component. This will ensure the user gets authanticated, before anything
wrapped by `Authenticated` gets mounted / rendered:

class SomeComponent extends React.Component {
render() {
return <p>Some component that needs an authenticated user...</p>
}
```js
function ProtectedComponent() {
return (
<Authenticated>
<ProtectedComponent />
</Authenticated>
)
}
```

const ProtectedComponent = authenticated()(SomeComponent)
Lastly, if you require the access token, you can use the `useToken()` hook:

const SomeOtherComponent = () => (<p>This is some other component</p>)
const ProtectedComponent = authenticated()(() => (<SomeOtherComponent />))
```js
function ComponentWithToken() {
const { access_token } = useToken()
const [data, setData] = useState(null)
useEffect(() => {
if (!data) {
fetchData({ token: access_token }).then(setData)
}
}, [access_token])
return (
// render the data (or a loading indicator, while data === null)
)
}
```

## Using the `access_token`
Note: You need to provide your own `fetchData()` function.

A protected component isn't too valuable on its own, you may need an access
token when speaking to an API. Anywhere the access token can be accessed like
this:
## Options

```
import { getLocalToken } from 'react-u5auth'
In addition to the required properties (`clientId` etc), the following properties can be specified when calling `createAuthContext()`:

- `busyIndicator`: A React element to be rendered while logging in, e.g. `<Spinner />`.
- `fetch`: HTTP requests to talk to the OAuth2 provider are done using `window.fetch`, unless you specify your own `fetch` function as a property.
- `storage`: By default, authentication information (the token) is kept in `window.sessionStorage`. If you want to use different storage (e.g. `window.localStorage`), set this property. (TODO: won't work yet, as we don't check expiry of tokens!)
- `tokenEndpoint`: The default token endpoint is `${provider}/token`. Configure a different token endpoint here, if your OAuth2 provider does not follow this convention.

...
const token = getLocalToken()
...

# Example

Check the live demo (see above), also checkout [the test app](./src/App.js).

You can run the example, after cloning the repo, and:

```bash
npm i
npm run start
```

Please note: There is something fishy here about the `access_token`
being kept in global state. See
[this issue](https://github.com/Uber5/react-u5auth/issues/3).
... then connect to http://localhost:3001.


# Status

Expand Down
Loading